带有静态成员约束的泛型类型的类型推断失败 [英] Type inference failing on generic type with static member constraint

查看:117
本文介绍了带有静态成员约束的泛型类型的类型推断失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我定义了以下类型(从代码简化):

I have defined the following type (simplified from code):

type Polynomial<'a when 'a :(static member public Zero : 'a) 
                and 'a: (static member (+): 'a*'a -> 'a) 
                and 'a : (static member (*): 'a*'a -> 'a) >  =
    | Polynomial of 'a list
    with 
    static member inline (+) (x: Polynomial<'a> , y : Polynomial<'a>) : Polynomial<'a>= 
        match x,y with
        |Polynomial xlist, Polynomial ylist ->
            let longer, shorter = 
                if xlist.Length> ylist.Length then xlist, ylist
                else ylist, xlist
            let shorterExtended = List.append shorter (List.init (longer.Length - shorter.Length) (fun _ -> LanguagePrimitives.GenericZero<'a>))
            List.map2 (+) longer shorterExtended |> Polynomial

当我建立时,我得到警告:

When I build I get the warning :


warning FS0193:当(^ a或^?23604):(static> member(+):^ a * ^?23604 - > ^?23605时,类型参数缺少约束' )'b / b>

warning FS0193: A type parameter is missing a constraint 'when ( ^a or ^?23604) : (static >member ( + ) : ^a * ^?23604 -> ^?23605)'

对最后一行中的更长一词。据我所知,它应该能够推断出它总是添加两个'a'成员。
我该如何摆脱这个问题?

on the word "longer" in the last line. As far as I can see it should be able to infer that it is always adding two members of 'a. How can I get rid of this?

推荐答案

这是一个有趣的问题,使用绑定函数而不是静态成员似乎不会触发相同的警告。假设在绑定和成员函数中静态类型参数的分辨率存在差异。

This is an interesting question, using a let bound function instead of a static member doesn't seem to trigger the same warning. Presumably there are differences between the resolution of static type parameters in let bound and member functions.

module PolyAdder =
    let inline addPoly x y = 
        match x,y with
        |Polynomial xlist, Polynomial ylist ->
            let (longer : ^a list), (shorter : ^a list) = 
                if xlist.Length > ylist.Length then xlist, ylist
                else ylist, xlist
            let shorterExtended : ^a list = shorter @ (List.init (longer.Length - shorter.Length) (fun _ -> LanguagePrimitives.GenericZero< ^a >))
            // no warning here!
            List.map2 (+) longer shorterExtended |> Polynomial

然后,您可以使用a扩展 Polynomial +运算符基于上面的限制函数:

You can then extend Polynomial with a + operator based on the let bound function above:

type Polynomial with
    static member inline (+) (x, y) = PolyAdder.addPoly x y

仍然没有警告,+运算符正常工作

There is still no warning and the + operator works normally

let poly1 = [1; 2; 5; 6; 8] |> Polynomial
let poly2 = [7; 1; 2; 5;] |> Polynomial
let polyAdded = poly1 + poly2

这篇关于带有静态成员约束的泛型类型的类型推断失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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