【问题标题】:Convert a list of characters (or array) to a string将字符列表(或数组)转换为字符串
【发布时间】:2010-02-28 17:01:48
【问题描述】:

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

换一种说法,我如何反转List.ofSeq "abcd"

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

【问题讨论】:

    标签: f#


    【解决方案1】:

    我之前曾问过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"
    

    【讨论】:

    • 好的,这个限制在性能方面是有意义的(创建一个可能难以优化的 lambda 可能会以难以检测的方式损害性能)。关于为什么“新”是可选的任何指针?为了使通过反射创建对象与 Ocaml/F# 语法更好地融合?谢谢!
    • 很难选择一个答案,我会选择这个,因为它引用了另一个相关问题。 :-)
    • “对象构造函数似乎不可组合,因此您不能将它们作为函数传递。”这终于改变了。 github.com/fsharp/FSharpLangDesign/blob/master/FSharp-4.0/…
    • 我在尝试第三个 sn-p 时遇到编译器错误,它显示“类型名称和/或对象构造函数的使用无效......”
    • @reggaeguitar 该错误意味着您正在运行旧版本的 F#。您需要更新到 VS 2015 附带的 F# 4.0。
    【解决方案2】:

    在 F# 中使用字符串有时会有点不舒服。我可能会使用与达里奥相同的代码。 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, _>
    

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

    【讨论】:

      【解决方案3】:

      你的方法:

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

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

      F# 的语法/类型推断系统似乎无法将像 new String 这样的 .NET 构造函数识别为柯里化函数(这会阻止您使用流水线)。

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-07-14
          • 2022-08-17
          • 2012-05-04
          • 1970-01-01
          相关资源
          最近更新 更多