Question

I want to define sumOfSquares without explicity using parameter, relying instead on functional composition

Here's my code below

let sumOfSquares = Seq.map (fun n -> n * n) >> Seq.sum

However, I got the following error

stdin(80,5): error FS0030: Value restriction. The value 'sumOfSquares' has been inferred to have generic type

val sumOfSquares : ('_a -> int) when '_a :> seq<int> 

Either make the arguments to 'sumOfSquares' explicit or, if you do not intend for it to be generic, add a type annotation.

One way to resolve it is by using parameters

let sumOfSquares nums = nums |> Seq.map (fun n -> n * n) |> Seq.sum

and this will work. However, I want to see if I can define sum of squares by using composition alone

Update

Here's a nice article describing the issue I've encountered: Value Restriction.

Was it helpful?

Solution

Make a type annotation:

let sumOfSquares : seq<int> -> int = 
    Seq.map (fun n -> n * n) >> Seq.sum

OTHER TIPS

So lets see what happens when the type inference tries to work here. First you have

Seq.map (fun n -> n * n) >> Seq.sum

Now as Seq allows for anything that implements Seq, we can input int list int[] or many others.

As a result, you get this as the type

val sumOfSquares : ('_a -> int) when '_a :> seq<int> 

Now the problem is that sumofSquares is a value (which is a function). Unfortunately, you can't have a generic value in a top level binding. You can though have a generic function, if you make the arguments explicit.

As a result, one alternative to a type annotation is to make the argument explicit like so

let sumOfSquares s= s |> Seq.map (fun n -> n * n) |> Seq.sum

And this works

Searching SO for "value restriction errors" should give some more examples of this problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top