Convert a list of characters (or an array) to a string

How to convert from a list of characters to a string?

In other words, how do I cancel List.ofSeq "abcd" ?

UPDATE: new System.String (List.ofSeq "abcd" |> List.toArray) |> printfn "%A" works fine, with or without new , but List.ofSeq "abcd" |> List.toArray) |> new System.String |> printfn "%A" fails. Why?

+12
source share
4 answers

I asked a similar question earlier. It seems that object constructors are not composite, so you cannot pass them as a function.

 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" 

Update Constructors are first-class features with F # 4.0

 List.ofSeq "abcd" |> List.toArray |> System.String |> printfn "%A" 
+20
source

Working with strings in F # is sometimes a little inconvenient. I would probably use the same code as Dario. Grammar F # does not allow the use of constructors as functions of the first class, so you, unfortunately, cannot process all the processing in one pipeline. In general, you can use static members and instance methods as functions of the first class, but not instance properties or constructors.

Anyway, there is a very nasty trick that you can use to turn a constructor into a function value. I would not recommend using it, but I was very surprised to see that it really works, so I thought it might be worth sharing it:

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

This defines the function that will be included at the time of compilation, which requires that the parameter of the first type has a constructor that takes the value of the parameter of the second type. This is indicated as a compilation time limit (since .NET generators cannot express this). In addition, F # does not allow you to specify this using the usual syntax for specifying constructor constraints (which should take unit as an argument), but you can use the compiled name of the constructors. Now you can write, for example:

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

And you can also use the ctor result as a first-class function:

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

As I said, I think this is mostly curiosity, but quite interesting :-).

+10
source

Your approach:

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

- This is a decision that I usually get too.

The G # grammar / type system just seems unable to recognize the .NET constructor, such as new String , like the curried function (which prevents you from using pipelining).

+4
source

Just ran into a similar problem and came up with the following solutions:

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

Source: https://habr.com/ru/post/903223/


All Articles