问题
So I'm getting the "This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type 'CountType'." warning, and the constraint is causing a problem in other bits of the code.
I've tried making the type explicitly generic, but it's not working. I've put this code on tryfsharp to make it easier to play with.
Apologies for the mound of code, I tried cutting it down and simplifying some types.
module Stuff
type CountType = Container of seq<string> * int | Collection of seq<CountType> * int
type Label = string * seq<string> * int
let rec generatePairsInternal (buffer:('a*'a) list) (seqa: 'a list)(seqb: 'a list) =
match seqa with
| head::tail ->
let newBuffer = seqb |> List.map (fun x->(head,x)) |> List.append buffer
generatePairsInternal newBuffer tail seqb
|_ -> buffer
let generatePairs = generatePairsInternal []
let ($) f (a,b) = f a b
let funcOnceWithEachPair (func:'a->'a->'b option) (seqa:'a seq) (seqb: 'a seq): 'b option list =
let (lista,listb) = (seqa |> Seq.toList, seqb |> Seq.toList)
let pairs = generatePairs lista listb
pairs |> List.map (($) func)
let crossAndDiscard func children1 children2 =
(funcOnceWithEachPair func children1 children2) |> List.filter Option.isSome |> List.map Option.get//This is probably bad.
let countTypeFunc (countType1:CountType) (countType2:CountType) =
Some countType1
let doSomethingRandom (countTypes1:CountType list) (countTypes2:CountType list): CountType list =
crossAndDiscard countTypeFunc countTypes1 countTypes2
let labelFunc (label1:Label) (label2:Label) =
Some label1
let doSomethingRandom (countTypes1:Label list) (countTypes2:Label list): Label list =
crossAndDiscard labelFunc countTypes1 countTypes2
回答1:
The problem is that F# only allows functions to be generic, so when you do this:
let generatePairs = generatePairsInternal []
generatePairs
is considered to be a value (even though its type is that of a function) and is has the types constrained, if you change it to something like this:
let generatePairs listA = generatePairsInternal [] listA
It should work.
来源:https://stackoverflow.com/questions/24936891/this-construct-causes-code-to-be-less-generic-than-indicated-by-the-type-annotat