The Some operator in F# almost shouldn’t exist. There is one and only one instance where it makes sense.
let mutable a = Some(5)
let Foo (arg1 : int option, arg2 : int option) = match arg1, arg2 with | None, None -> 0 | arg1, None -> arg1.Value | None, arg2 -> arg2.Value | _, _ -> arg1.Value + arg2.Value
Normally I pass values of option<int> to it, but once in awhile I would like to pass a normal int.
let b = Foo(a, 5) // Error: This expression has type int but is here used with type int option
So? You don’t have to understand that the set of all option<int> values contains all int values. Or in other words, it is always safe to convert a int into an option<int>. I’ll even go one step further. It is always safe to convert any T into any option<T>.
SO WHY ARE YOU WASTING MY TIME?
Ok, lets try something a little bit easier. Every language high on the chain than assembly knows about implicit numeric conversions, right? Well lets try that with F#.
let c = 10 let d = (decimal)2.5 let e = c + d //Type constraint mismatch. The type int is not compatible with type decimal
What do you mean “the type int is not compatible with the type decimal”? Every possible int can be exactly represented as a decimal, so what the heck are you complaining about?
Maybe I’m using it wrong. Maybe I should try F#’s famous automatic generalization of functions.
let SimplyAdd x y = x + y //Type constraint mismatch. The type int is not compatible with
type decimal The type 'int' is not compatible with the type 'decimal' let f = SimplyAdd c d //Type constraint mismatch. The type int is not compatible with type
decimal The type 'int' is not compatible with the type 'decimal'
Cool. Now I got errors on tow separate lines, and they each tell me the same thing twice. Where else can you get four error messages for the price of one type conversion?
If the F# designers were to put in just a little bit of compiler magic so that the language would do the semantically right thing, F# would be a really pleasant language to work with. But like the way they introduced option-style nulls without removing CLR nulls, making something technically consistent at the expense of both inconsistent syntax and inconsistent semantics is just wrong.