将字符列表(或数组)转换为字符串

时间:2010-02-28 17:01:48

标签: f#

如何将字符列表转换为字符串?

换句话说,如何撤销List.ofSeq "abcd"

更新:new System.String (List.ofSeq "abcd" |> List.toArray) |> printfn "%A"似乎工作正常,有或没有new,但List.ofSeq "abcd" |> List.toArray) |> new System.String |> printfn "%A"失败。为什么呢?

4 个答案:

答案 0 :(得分:23)

之前我曾问similar question一次。似乎对象构造函数不可组合,因此您无法将它们作为函数传递。

List.ofSeq "abcd" |> List.toArray |> (fun s -> System.String s) |> printfn "%A"
List.ofSeq "abcd" |> List.toArray |> (fun s -> new System.String(s)) |> printfn "%A"

<强>更新 构造函数是F#4.0的第一类函数

List.ofSeq "abcd" |> List.toArray |> System.String |> printfn "%A"

答案 1 :(得分:13)

在F#中使用字符串有时会有点不舒服。我可能会使用与Dario相同的代码。 F#语法不允许使用构造函数作为第一类函数,因此遗憾的是,您无法在单个管道中执行整个处理。通常,您可以将静态成员和实例方法用作第一类函数,但不能使用实例属性或构造函数。

无论如何,你可以使用一个非常讨厌的技巧将构造函数转换为函数值。我不建议实际使用它,但我很惊讶地看到它确实有效,所以我认为值得分享它:

let inline ctor< ^R, ^T 
  when ^R : (static member ``.ctor`` : ^T -> ^R)> (arg:^T) =
   (^R : (static member ``.ctor`` : ^T -> ^R) arg)

这定义了一个在编译时内联的函数,它要求第一个类型参数具有一个构造函数,该构造函数接受第二个类型参数的值。这被指定为编译时约束(因为.NET泛型不能表达这一点)。此外,F#不允许您使用通常的语法指定构造函数约束(必须以unit作为参数)来指定它,但您可以使用编译器的编译名称。现在你可以写例如:

// just like 'new System.Random(10)'
let rnd = ctor<System.Random, _> 10
rnd.Next(10)

您还可以使用ctor的结果作为第一类函数:

let chars = [ 'a'; 'b'; 'c' ]
let str = chars |> Array.ofSeq |> ctor<System.String, _>

正如我所说的,我认为这主要是一种好奇心,但却非常有趣:-)。

答案 2 :(得分:5)

你的方法:

new System.String (listOfChars |> List.toArray)

是我通常最终得到的解决方案。

F#的语法/类型推理系统似乎无法将new String之类的.NET构造函数识别为curry函数(这会阻止您使用流水线操作)。

答案 3 :(得分:1)

刚遇到类似的问题,并提出了这个解决方案:

List.fold (fun str x -> str + x.ToString()) "" (List.ofSeq "abcd")