F#printfn异常

时间:2012-07-29 09:43:28

标签: f#

任何人都可以解释为什么会导致错误:

let xs = [| "Mary"; "Mungo"; "Midge" |]

Array.iter printfn xs

虽然这不是:

Array.iter printfn [| "Mary"; "Mungo"; "Midge" |]

2 个答案:

答案 0 :(得分:7)

printfn的签名是Printf.TextWriterFormat<'a> -> 'a。编译器将字符串的字面值推断为Printf.TextWriterFormat<unit>,但不能使用动态字符串。

您可以通过添加正确的类型注释来帮助第一个示例中的编译器:

let xs: Printf.TextWriterFormat<unit> [] = [| "Mary"; "Mungo"; "Midge" |]
Array.iter printfn xs

或使用显式构造函数:

let xs = [| "Mary"; "Mungo"; "Midge" |]
Array.iter (fun s -> printfn <| Printf.TextWriterFormat<unit>(s)) xs

一般来说,这样做过于冗长。因此,为字符串指定格式字符串,例如"%s",为覆盖"%O"方法的类型指定ToString(),这是最好的方法:

let xs = [| "Mary"; "Mungo"; "Midge" |]
Array.iter (printfn "%s") xs

答案 1 :(得分:3)

除了@ pad的优秀答案。

混淆的主要原因是对参数发生的事情的误解。让我们看一下单次迭代。它应该是

printfn "%s" "Mary" // or whatever default format specifier instead of %s

但事实上,它是

printfn "Mary" ()

因此"Mary"不是要格式化的字符串。 这是格式说明符,非常无用,但非常适合格式化unit

尝试对您的样本进行此修改:

Array.iter printfn [| "Mary %s"; "Mungo"; "Midge" |]

它将拒绝编译。