Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Value restriction: The type 'bar' has been inferred to have generic type

Tags:

f#

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.

like image 588
BitTickler Avatar asked Sep 08 '16 14:09

BitTickler


1 Answers

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.

like image 194
Fyodor Soikin Avatar answered Oct 23 '22 19:10

Fyodor Soikin