type Alignment =
| Horizontal
| Vertical
let getMainAttr = function
| Horizontal -> fst
| Vertical -> snd
let check alignment =
let mainAttr = getMainAttr alignment
mainAttr (2,3) |> ignore
mainAttr (2.0, 3.0) // error
val getMainAttr : _arg1:Alignment -> ('a * 'a -> 'a)
mainAttr : (int * int -> int) // because of the value restriction
it seems the only way to make it generic is to make it explicit, e.g. let mainAttr x = getMainAttr alignment x
However, thus it no longer utilize closure, so that each time mainAttr is called alignment has to be checked.
Is there any way to only check alignment once as well as being generic?
As @Daniel describes, you’re hitting the value restriction limitation which disallows creating generic values that are result of some F# computation (even if the value is a function). You can find more information about this in other SO questions and there is also an article about advanced points. The reason for this restriction is that generic values can introduce a loophole in the type safety.
In your example, you do not really need to worry, because executing the
getMainAttrfunction repeatedly is not going to add that much overhead. If the function did a more complex computation, you could return an interface with a generic method (instead of a simple function):