这种构造导致代码的通用性低于类型注释所指示的通用性 [英] This construct causes code to be less generic than indicated by the type annotations

查看:49
本文介绍了这种构造导致代码的通用性低于类型注释所指示的通用性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我得到了此构造导致代码的通用性低于类型注释所指示的类型.类型变量'a已被约束为类型'CountType'."警告,并且约束导致代码的其他位出现问题.

我试图使该类型显式泛型,但无法正常工作.我已将此代码放在 tryfsharp 上,以使其更容易使用./p>

为这堆代码道歉,我尝试将其缩减并简化某些类型.

 模块填充类型CountType = seq< string>的容器.* int |seq< CountType>的集合.* int类型Label =字符串* seq< string>* int让rec generate generatePairsInternal(buffer :('a *'a)list)(seqa:'a list)(seqb:'a list)=匹配seqa与|head :: tail->让newBuffer = seqb |>List.map(fun x->(head,x))|>List.append缓冲区generatePairsInternal newBuffer尾部seqb| _->缓冲让generatePairs = generatePairsInternal []令($)f(a,b)= f a b让funcOnceWithEachPair(func:'a->'a->'b选项)(seqa:'a seq)(seqb:'a seq):'b选项列表=let(lista,listb)=(seqa | gt; Seq.toList,seqb |> Seq.toList)让对= generatePairs lista listb对|>List.map(($$ func)let crossAndDiscard func children1 children2 =(funcOnceWithEachPair func children1 children2)|>List.filter Option.isSome |>List.map Option.get//这可能是不好的.让countTypeFunc(countType1:CountType)(countType2:CountType)=一些countType1让doSomethingRandom(countTypes1:CountType列表)(countTypes2:CountType列表):CountType list =crossAndDiscard countTypeFunc countTypes1 countTypes2让labelFunc(label1:Label)(label2:Label)=一些标签1let doSomethingRandom(countTypes1:Label列表)(countTypes2:Label列表):标签列表=crossAndDiscard labelFunc countTypes1 countTypes2 

解决方案

问题是F#仅允许函数通用,因此在执行此操作时:

  let generatePairs = generatePairsInternal [] 

generatePairs 被认为是一个值(即使其类型是函数的类型),并且如果将其更改为以下形式,则其类型也受约束:

  let generatePairs listA = generatePairsInternal [] listA 

应该可以.

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

解决方案

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.

这篇关于这种构造导致代码的通用性低于类型注释所指示的通用性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆