Conversione di un elenco di caratteri (o array) di una stringa

come si fa a convertire da un elenco di caratteri di una stringa?

Per dirla in altro modo, come faccio a invertire List.ofSeq "abcd"?

AGGIORNAMENTO: new System.String (List.ofSeq "abcd" |> List.toArray) |> printfn "%A" sembra funzionare bene, con o senza new, ma List.ofSeq "abcd" |> List.toArray) |> new System.String |> printfn "%A" non riesce. Perché?

 

4 Replies
  1. 25

    Ho chiesto un domanda simile una volta prima. Sembra che i costruttori degli oggetti non sono componibili in modo che non è possibile passare loro come una funzione.

    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"

    Aggiornamento
    I costruttori sono di prima classe, funzioni di F# 4.0

    List.ofSeq "abcd" |> List.toArray |> System.String |> printfn "%A"
    • OK, questa limitazione rende il senso performance-saggio (la creazione di una lambda che probabilmente duro per ottimizzare la distanza probabilmente può compromettere le prestazioni in modo che è difficile da rilevare). Qualsiasi puntatore sul perché “nuovo” è opzionale? Per rendere la creazione di oggetti di riflessione si armonizzano meglio con il Ocaml/F# sintassi? Grazie!
    • Difficile scegliere una delle risposte, ho scelto questa perché si fa riferimento a un’altra domanda correlata. 🙂
    • “Sembra che i costruttori degli oggetti non sono componibili in modo che non è possibile passare loro come una funzione.” Questo è finalmente cambiando. github.com/fsharp/FSharpLangDesign/blob/master/FSharp-4.0/…
    • Ottengo un errore del compilatore quando si cerca il terzo frammento, si dice “utilizzo non Valido di un tipo di nome e/o il costruttore dell’oggetto….”
    • quell’errore significa che è in esecuzione una versione precedente di F#. È necessario aggiornare a F# 4.0, che viene fornito con VS 2015.
    • > i Costruttori sono di prima classe, funzioni di F# 4.0 è un gioiello. Grazie!

  2. 14

    Lavorare con le stringhe in F# è a volte un po ‘ a disagio. Io probabilmente usare lo stesso codice come Dario. F# grammatica non permette l’utilizzo di costruttori come funzionalità di prima classe, così, purtroppo, non può fare tutta la lavorazione in una singola pipeline. In generale, è possibile utilizzare i membri statici e metodi di istanza come una funzionalità di prima classe, ma non di proprietà di un’istanza o di costruttori.

    Comunque, c’è davvero brutto trucco è possibile utilizzare per attivare un costruttore in un valore della funzione. Vorrei raccomandare di non utilizzo, ma sono stato molto sorpreso di vedere che in realtà funziona, così ho pensato che potrebbe essere la pena di condivisione:

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

    Questo definisce una funzione che saranno sostituite in fase di compilazione, il quale prevede che il primo parametro di tipo ha un costruttore che accetta un valore del secondo parametro di tipo. Questo è specificato come un tempo di compilazione di vincolo (perché .NET generics non può esprimersi). Inoltre, F# non consentono di specificare questo utilizzando la solita sintassi per la definizione di costruttore di vincoli (che deve prendere unit come argomento), ma è possibile utilizzare il compilati nome dei costruttori. Ora si può scrivere per esempio:

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

    E si può utilizzare anche il risultato di ctor di prima classe è funzione di:

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

    Come ho detto, penso che questo è principalmente una curiosità, ma abbastanza interessante :-).

    • +1: la freddezza!!!
  3. 5

    Il tuo approccio:

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

    è la soluzione che di solito finiscono con troppo.

    F#’s grammatica/sistema di inferenza semplicemente non sembra in grado di riconoscere .NET costruttore new String come al curry funzione (che impedisce di utilizzare il pipelining).

  4. 1

    Appena affrontato un problema simile, e si avvicinò con questa soluzione:

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

Lascia un commento