如何将printf样式的函数传递给F#中的另一个函数

编程入门 行业动态 更新时间:2024-10-24 11:19:33
本文介绍了如何将printf样式的函数传递给F#中的另一个函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我想在F#中创建一个函数,该函数接受printf样式的函数作为参数,并使用该参数输出数据.用法如下所示:

I'd like to make a function in F# that accepts a printf-style function as an argument, and uses that argument to output data. Usage would be something like the following:

OutputStuff printfn

我的第一个尝试是让编译器为我解决所有问题:

My first attempt was to let the compiler figure it all out for me:

let OutputStuff output = output "Header" output "Data: %d" 42

之所以失败,是因为它确定output是使用string并返回unit的函数,因此第二次调用失败.

That fails because it decides that output is a function taking string and returning unit, so the second call fails.

接下来,我尝试声明output具有与printfn相同的签名:

Next I tried declaring output to have the same signature as printfn:

let OutputStuff (output : Printf.TextWriterFormat<'a> -> 'a) = output "Header" output "Data: %d" 42

这失败了,因为编译器确定output的实际类型是Printf.TextWriterFormat<string> -> unit,因此第二次调用再次失败.它还会生成警告FS0064,该警告表明对output的首次调用导致代码的通用性低于类型注释,这是问题的症结所在.

This fails because the compiler decides that the real type of output is Printf.TextWriterFormat<string> -> unit, so again the second call fails. It also generates warning FS0064 indicating that the first call to output causes the code to be less generic than the type annotations, which is the crux of the issue here.

最后,我尝试将输出函数声明为单独的类型缩写:

Last, I tried declaring the output function as a separate type abbreviation:

type OutputMe<'a> = Printf.TextWriterFormat<'a> -> 'a let OutputStuff (output : OutputMe<'a>) = output "Header" output "Data: %d" 42

此操作失败,结果与上一次尝试相同.

This fails with the same results as the previous attempt.

我如何说服编译器不要专门化output的类型并将其保留为Printf.TextWriterFormat<'a> -> 'a?

How do I convince the compiler to not specialize the type of output and leave it as Printf.TextWriterFormat<'a> -> 'a?

推荐答案

问题是,当您说(output : Printf.TextWriterFormat<'a> -> 'a)时,表示"存在,其中某些'a的输出需要Printf.TextWriterFormat<'a>到'a".相反,您要说的是全部 'a输出可以使用Printf.TextWriterFormat<'a>并返回'a.

The problem is that when you say (output : Printf.TextWriterFormat<'a> -> 'a), that means "there is some 'a for which output takes a Printf.TextWriterFormat<'a> to an 'a". Instead, what you want to say is "for all 'a output can take a Printf.TextWriterFormat<'a> and return a 'a.

用F#表示很难理解,但是要用具有泛型方法的类型来实现:

This is a bit ugly to express in F#, but the way to do it is with a type with a generic method:

type IPrinter = abstract Print : Printf.TextWriterFormat<'a> -> 'a let OutputStuff (output : IPrinter) = output.Print "Header" output.Print "Data: %d" 42 OutputStuff { new IPrinter with member this.Print(s) = printfn s }

更多推荐

如何将printf样式的函数传递给F#中的另一个函数

本文发布于:2023-11-08 07:51:47,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1568789.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:函数   如何将   样式   printf

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!