Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can this be expressed in point free style?

Given the following expression to sum an IEnumerable of numbers:

let sum l = l |> Seq.reduce(+)  //version a

is it possible to eliminate the argument--like so?

let sum = Seq.reduce(+)    //version b

I get an error from the F# compiler (FS0030) and I seem to recall having seen something about an "eta conversion" being involved but unfortunately my knowledge of lambda calc is too limited to follow how eta conversion is involved.

Can the argument be eliminated as in version b?

Would someone please point me to literature that would explain an eta conversion and how it would come into play in this particular piece of code?

FS0030:

stdin(1,5): error FS0030: Value restriction. The value 'sum' has been inferred to have generic type val sum : ('_a -> int) when '_a :> seq Either make the arguments to 'sum' explicit or, if you do not intend for it to be generic, add a type annotation.

like image 464
Onorio Catenacci Avatar asked Dec 01 '22 18:12

Onorio Catenacci


2 Answers

"Eta conversion" simply means adding or removing the argument. The problem you are hitting is called value restriction. In ML languages, a value declared as a value, ie. declared without explicit arguments, cannot have a generic type, even if it has a function type. Here is some relevant literature. The idea is to prevent a ref cell from holding values of different types. For example, without value restriction, the following program would be allowed:

let f : 'a -> 'a option =
    let r = ref None
    fun x ->
        let old = !r
        r := Some x
        old

f 3           // r := Some 3; returns None : int option
f "t"         // r := Some "t"; returns Some 3 : string option!!!

As kvb said, if you do not intend the function to be generic, then you can add a type signature and use point-free style.

like image 53
Tarmil Avatar answered Dec 16 '22 00:12

Tarmil


You can do it in point free style, but you need to add a (monomorphic) type annotation:

let sum : int seq -> int = Seq.reduce (+)
like image 37
kvb Avatar answered Dec 16 '22 00:12

kvb