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

Mir*_*anu 17 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"失败.为什么?

gra*_*bot 26

我之前曾问过一个类似的问题.似乎对象构造函数不可组合,因此您无法将它们作为函数传递.

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"
Run Code Online (Sandbox Code Playgroud)

更新 构造函数是F#4.0的一流函数

List.ofSeq "abcd" |> List.toArray |> System.String |> printfn "%A"
Run Code Online (Sandbox Code Playgroud)


Tom*_*cek 14

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

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

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

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

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

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

let chars = [ 'a'; 'b'; 'c' ]
let str = chars |> Array.ofSeq |> ctor<System.String, _>
Run Code Online (Sandbox Code Playgroud)

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


Dar*_*rio 5

你的方法:

new System.String (listOfChars |> List.toArray)
Run Code Online (Sandbox Code Playgroud)

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

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