tags:

views:

155

answers:

4

I am trying to have a list of functions, but seem to be coming up empty handed. The basic code is something like this:

let doSomething var  =
    var

let doSomething2 var  =
    var

let listOfStuff = [doSomething; doSomething2]

and I am getting the following exception:

Error 2 Value restriction. The value 'listOfStuff' has been inferred to have generic type val queue : ('_a -> '_a) list Either define 'queue' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation. C:\fsharp\SentimentFramework\TradeSignalProcessor\Program.fs 16 9 TradeSignalProcessor

I tried adding the [<GeneralizableValue>] attribute but that didn't work...

A: 

Lists should all have the same type. Try using a tuple for this instead.

...and try doing as the error suggests. Give your inputs a type at the very least.

Shaun
+1  A: 

You want a list, composed of functions? I would think it would go like this:

let f x = x + 1
let g x = x + 1

let listOfFunc = [f; g]

If you need to specify the parameter, just remember to use the type notation:

let f (x:string) = x + "1"
Tejs
exactly. notice how the functions are of the same type?
Shaun
Does the OP want to use two different function types in a list?
Tejs
I added the types declarations to the functions and everything cleaned up. I must have some ambiguity somewhere thank you for your help
akaphenom
+2  A: 

As others have noted, giving explicit types to your functions or to your list will resolve your issue. The reason that this occurs is that functions can have generic types, but (generally speaking) values can't. The compiler has inferred that both of your functions have type 'a -> 'a for any type 'a. This means that your list would have type ('a -> 'a) list, which is a generic type and is invalid for a value. Specifying an explicit type such as let listOfStuff : (int -> int) list = ... will resolve the ambiguity.

Having said that, note that I can't reproduce this exact issue in the latest version of the compiler (F# 2.0.0.0). It appears that list expressions can be generalized (presumably since they are side-effect free). However I see an analogous error when I use an array expression instead.

kvb
+1  A: 

You have ancountered 'the value restriction'. You are not allowed to define generic 'values' like the listOfStuff-array.

There are a few previous questions on this subject that you might find useful and Microsoft writes about this under the topic "Automatic Generalization".

Edit: Dmitry Lomov has written a great article on the subject here: "Finer Points of F# Value Restriction".

Johan Kullbom
thank you - ngreat articles
akaphenom