I'm implementing a simple conversion string to integer convertor in F#; the logic is, e.g from string to uint32:
let inline sToUint s =
let mutable v = 0u
for c in s do
v <- v * 10u + uint32 c - uint32 '0'
v
Now I would like to use this implementation for other integer types, e.g. uint64. How can I implement a single generic function to do that?
Thank for all, SRTP (as used in the answers) is what I need for such a situation. The following implementation is just slightly changed from the answer of @Brian Berns
// (char -> ^a) -> (string -> ^b)
let inline sToNum f =
let tenTimes v = (v <<< 3) + (v <<< 1)
fun (s: string) ->
let mutable v = Unchecked.defaultof<_>
for c in s do
v <- (tenTimes v) + f c - f '0'
v
You can do something like this:
let inline sToNum f =
let ten = Seq.replicate 10 LanguagePrimitives.GenericOne |> Seq.sum
fun s ->
let mutable v = LanguagePrimitives.GenericZero
for c in s do
v <- v * ten + f c - f '0'
v
let sToUint16 = sToNum uint16
let sToUint32 = sToNum uint32
let sToUint64 = sToNum uint64
let sToInt16 = sToNum int16
let sToInt32 = sToNum int32
let sToInt64 = sToNum int64
Test code:
sToUint16 "123" |> printfn "%A" // 123us
sToUint32 "123" |> printfn "%A" // 123u
sToUint64 "123" |> printfn "%A" // 123UL
sToInt16 "123" |> printfn "%A" // 123s
sToInt32 "123" |> printfn "%A" // 123
sToInt64 "123" |> printfn "%A" // 123L
Note that sToNum returns a lambda, so it doesn't have to recompute ten each time. (You could even cache the value of f '0' as well, to shave off a little more time.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With