2

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
  • 1
    By the way, you can replace List.filter Option.isSome |> List.map Option.get with List.choose id... :) Also, you have doSomethingRandom defined twice - you cannot overload functions, only methods. Commented Jul 24, 2014 at 14:59

1 Answer 1

9

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.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.