Reputation: 6888
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...
Upvotes: 1
Views: 1902
Reputation: 4243
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".
Upvotes: 1
Reputation: 55184
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.
Upvotes: 3
Reputation: 41246
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"
Upvotes: 3
Reputation: 4018
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.
Upvotes: 0