Search code examples
.netstringf#functional-programmingseq

Get a char at a specified position in the string


How can I get a char at a specified position in the string in a FP way (i.e. no dirty .[index] hack)?

If I use Seq.item it will iterate all indexes until the n element, so make the function run very slow each time.

In the example bellow, if source is a string, it'll a O(1) access, else it'll a O(n) access.

let getItem index source =
    match box source with
    | :? string as string -> printfn "String"; string.[index]
    | _ -> printfn "Seq<char>"; Seq.item index source
let stringChar3 = getItem 3 "ABCD"
let seqChar3 = getItem 3 [ for c in ['A'..'D'] do yield c ]

val getItem : index:int -> source:seq<char> -> char
val stringChar3 : char = 'D'
val seqChar3 : char = 'D'

Solution

  • The String module in FSharp.Core isn't really very fully featured but you can create your own and include some reusable functions that play nicely with type inference, then you only need to write the explicit type annotations once and you can make use of type inference elsewhere.

    module String =
        let tryGetCharacter index (str : string) =
            if index >= 0 && index < str.Length then
                Some str.[index]
            else
                None
    
        let getCharacter index (str : string) =
            str.[index]