此构造使代码不如类型注释所指示的那样通用

时间:2014-07-24 14:44:16

标签: generics types f#

所以我得到了“这个结构导致代码比类型注释所指示的更不通用。类型变量'a被约束为类型'CountType'。”警告,并且约束导致代码的其他位出现问题。

我已经尝试将该类型明确地设为通用,但它不起作用。我已将此代码放在tryfsharp上,以便更轻松地使用。

对于代码堆的道歉,我尝试将其删除并简化某些类型。

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 个答案:

答案 0 :(得分:9)

问题是F#只允许函数是通用的,所以当你这样做时:

let generatePairs = generatePairsInternal []

generatePairs被认为是一个值(即使它的类型是函数的类型)并且具有受约束的类型,如果将其更改为如下所示:

let generatePairs listA = generatePairsInternal [] listA

它应该有用。