F# Pattern-matching by type -


how pattern-matching type of argument works in f#?

for example i'm trying write simple program calculate square root if number provided or return it's argument otherwise.

open system  let my_sqrt x =   match x   | :? float f -> sqrt f   | _ -> x   printfn "enter x" let x = console.readline()  printfn "for x = %a result %a" x (my_sqrt x)  console.readline() 

i error:

error fs0008: runtime coercion or type test type     'a           float     involves indeterminate type based on information prior  program point. runtime type tests not allowed on types. further type annotations needed. 

since sqrt works float check float type, guess there better solution - check if input number (in general) , if so, cast float?

the problem here type of x string. adding comes console.readline, kind of information stored in string possible determine @ runtime. means can't use neither pattern matching, nor pattern matching coercion here.

but can use active patterns. actual data stored in x known @ runtime, have parse string , see contains.

so suppose expecting float, can't sure since user can input whatever want. going try , parse our string:

let my_sqrt x =     let success, v = system.single.tryparse x // float in f# represented system.single in .net     if success sqrt v     else x 

but won't compile:

this expression expected have type float32 here has type string

the problem compiler inferred function return float32, based on expression sqrt (system.single.parse(x)). if x doesn't parse float, intend return it, , x string have inconsistency here.

to fix this, have convert result of sqrt string:

let my_sqrt x =     let success, v = system.single.tryparse x     if success (sqrt v).tostring()     else x 

ok, should work, doesn't use pattern matching. let's define our "active" pattern, since can't use regular pattern matching here:

let (|float|_|) input =     match system.single.tryparse input     | true, v -> v     | _ -> none 

basically, pattern match if input can correctly parsed floating point literal. here's how can used in initial function implementation:

let my_sqrt' x =     match x     | float f -> (sqrt f).tostring()     | _ -> x 

this looks lot function, note still had add .tostring() bit.

hope helps.


Comments

Popular posts from this blog

blackberry 10 - how to add multiple markers on the google map just by url? -

php - guestbook returning database data to flash -

delphi - Dynamic file type icon -