“无效约束:用于约束的类型已密封”无效

时间:2019-04-21 18:14:42

标签: f#

我希望使用F#的类型推断来简单地通过所调用的方法/函数来推断我的代码类型。

通过使用以下形式的扩展方法,可以很好地实现此目的。

[<Extension>]
type AttributeExtensions =
    [<Extension>]
    static member ``BroadcastOffset``<'a, 'b when 'a :> ``BroadcastOffset``<'b>> (this: 'a) = 
        this.``

当我有读取的代码

x.BroadcastOffset()

类型推断将开始,并推断x实际上必须是BroadcastOffset <'a>类型。

例如,如果我写的话,美中不足的是F#自己的类型

x.Value

F#不会推断出它的Option <_>,那是可以理解的,但是我可以使用相同的扩展技巧来达到目标​​?

[<Extension>]
type AttributeExtensions =
    [<Extension>]
    static member Value<'a,'b when 'a :> Option<'b>> (this: 'a) = 
        this.Value

并且从理论上讲应该是

x.Value()

应触发x为Option <_>

的推断

这种情况很糟糕,因为F#拒绝将扩展方法视为无效约束,因为Option <_>是密封的,因此'a只能有1个解决方案。

True'a只能有1个解决方案,但是在我的书中,不会使约束无效,它是完全有效的,只是微不足道的推断,而且由于这种过分的拒绝,我对使“值”触发器感到沮丧类型推断。

任何想法如何解决? (除了自己更改F#编译器之外。)

(我当然可以定义一个函数'Value',但是我的意图是使用F#从“方法”中推断类型,并且扩展方法适合简单函数不能满足的要求...我有我的理由)

1 个答案:

答案 0 :(得分:0)

我在使用您的代码时遇到了编译错误,然后将我认为您需要的内容分解为一个函数,然后在扩展中使用了该函数。这样我就可以打电话给.Value()了,结果证明它是'a option类型的,我想您应该这样做吗?

open System.Runtime.CompilerServices

let v (x : 'a option) = x.Value

[<Extension>]
type AttributeExtensions =
    [<Extension>]
    static member Value(this) = v(this)

let myFunc o = o.Value()