2010-02-28 322 views
12

如何将字符列表转换为字符串?将字符(或数组)的列表转换为字符串

换句话说,我该如何反转List.ofSeq "abcd"

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

回答

20

我问了一次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" 
+0

OK,这个限制是有道理的性能代价(创建拉姆达这可能是难以优化的方式走可能会损害性能是很难检测)。关于为什么'新'是可选的任何指针?通过反射使Ocaml/F#语法更好地创建对象?谢谢! – 2010-02-28 20:58:52

+0

很难挑选其中一个答案,我会选择这一个,因为它引用了另一个相关的问题。 :-) – 2010-03-01 11:33:00

+0

“看起来对象构造函数不可组合,所以你不能将它们作为函数传递。”这终于改变了。 https://github.com/fsharp/FSharpLangDesign/blob/master/FSharp-4.0/ClassNamesAsFunctionsDesignAndSpec.md – Endrju 2015-02-18 19:19:36

4

你的方法:

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

是解决方案,我通常也结束了。

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

10

在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, _> 

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

+0

+1:coolness !!! – Juliet 2010-02-28 23:32:18

0

就面临着类似的问题,以及与此解决方案提出了:

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