In the snippet below, I cannot see why I have to compose f
and g
the way function foo
does and why it does not work the way function bar
tries to do it.
let f a b = a,b
let g (a : 'a) (b : 'a) = a
let (>!) f1 f2 =
fun a b ->
let (x,y) = f1 a b
f2 x y
let foo = fun a b -> (f >! g) a b
let bar = f >! g
Can anyone explain to me, why bar
is not working? Given that foo
also has generic type, it makes no sense to me.
foo
is a function, while bar
is a value. Yes, it's a value of a function type, but still a value. There is a subtle difference there.
The F# compiler can "see" that foo
is a function, because it sees the fun ->
right after let
.
Your bar
, on the other hand, is a true value - a result obtained by invoking a different function (the operator >!
). F# has a rule (known as "value restriction") saying (in everyday terms) that values (unlike functions) cannot have generic types, unless generic arguments are specified explicitly, thus effectively making it a "type function". (it's a bit more complicated than that, read the links below for the full picture)
This is not specific to F#, though - other non-pure variants of ML have this as well. Here is a discussion of this rule for F#, and here's a discussion for SML.
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