This construct causes code to be less generic than indicated by the type annotations

我与影子孤独终老i 提交于 2021-02-10 09:07:57

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!