Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F#, char seq -> strings

Tags:

string

char

f#

seq

I was just researching this myself. I found that System.String.Concat works pretty well, e.g.

"abcdef01234567" |> Seq.take 5 |> String.Concat;;

assuming that you've opened System.


The functions in the Seq module only deal with sequences -- i.e., when you call them with a string, they only "see" a Seq<char> and operate on it accordingly. Even if they made a special check to see if the argument was a string and took some special action (e.g., an optimized version of the function just for strings), they'd still have to return it as a Seq<char> to appease the F# type system -- in which case, you'd need to check the return value everywhere to see if it was actually a string.

The good news is that F# has built-in shortcuts for some of the code you're writing. For example:

"abcdef01234567" |> Seq.take 5

can be shortened to:

"abcdef01234567".[..4]  // Returns the first _5_ characters (indices 0-4).

Some of the others you'll still have to use Seq though, or write your own optimized implementation to operate on strings.

Here's a function to get the distinct characters in a string:

open System.Collections.Generic

let distinctChars str =
    let chars = HashSet ()
    let len = String.length str
    for i = 0 to len - 1 do
        chars.Add str.[i] |> ignore
    chars

F# has a String module which contains some of the Seq module functionality specialised for strings.


F# has gained the ability to use constructors as functions since this question was asked 5 years ago. I would use String(Char[]) to convert characters to a string. You can convert to and from an F# sequence or an F# list, but I'd probably just use the F# array module using String.ToCharArray method too.

printfn "%s" ("abcdef01234567".ToCharArray() |> Array.take 5 |> String)

If you really wanted to use a char seq then you can pipe it to a String like so:

printfn "%s" ("abcdef01234567" |> Seq.take 5 |> Array.ofSeq |> String)