2010-02-28 320 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")