【问题标题】:inline and operator overloading woes内联和运算符重载问题
【发布时间】:2016-09-06 12:14:14
【问题描述】:

我正在试验内联和运算符....不是特定的应用程序。

基于阅读诸如 http://nut-cracker.azurewebsites.net/blog/2011/11/15/typeclasses-for-fsharp/ 但不理解。

所以。

我可以做

type HelperType = HelperType with   
   static member (=>) (d:HelperType,x: list<char>) = fun y -> x @ y    
   static member (=>) (d:HelperType,x:array<char>) = fun y -> Array.append x y
   static member (=>) (d:HelperType,x:string     ) = fun y -> x + y

let inline append x = HelperType => x

let x1 = append "" ""
let x1 = append [|'a'|] [|'b'|]

工作......并且有点了解发生了什么。

但是让我们尝试重载类型而不是值...所以我去...

type TypeOf<'t> = | TypeOf

type HelperType = HelperType with   
   static member (<*>) (d:HelperType,x:TypeOf<list<char>>     )   = fun x y -> x @ y
   static member (<*>) (d:HelperType,x:TypeOf<array<char>>     )   = fun x y -> Array.append x y

即我实际上不需要类型的值,只是一些代理类型值

我走了

let inline append2 (x : ^t) = (HelperType <*> (TypeOf :> TypeOf< ^t>)) x

我得到...

Error       A unique overload for method 'op_LessMultiplyGreater' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member HelperType.( <*> ) : d:HelperType * x:TypeOf<char array> -> ('a0 [] -> 'a0 [] -> 'a0 []), static member HelperType.( <*> ) : d:HelperType * x:TypeOf<char list> -> ('a0 list -> 'a0 list -> 'a0 list)

但是第一个工作示例和第二个工作示例之间有什么区别?

【问题讨论】:

    标签: f#


    【解决方案1】:

    两个附加函数之间的主要区别在于第二个知道要解析的类型,它将是'something'的 TypeOf ,它只是不知道'something',但第一个中的append示例不知道它将解析哪种类型,因此它将重载解析推迟到调用站点。

    因此第二个示例尝试进行重载解析并失败。

    更新

    您可能对以下内容感兴趣:

    type HelperType = HelperType with   
       static member (<*>) (d:HelperType, _:list<char> ) = fun (x:list<char>) y -> x @ y
       static member (<*>) (d:HelperType, _:array<char>) = fun (x:array<char>) y -> Array.append x y
    
    let inline append2 x y :'T = (HelperType <*> Unchecked.defaultof<'T>) x y
    

    但它需要提前知道返回类型:

    let x1 : array<char> = append2 [|'a'|] [|'b'|]
    

    或者您可以按照您的想法进行更改:

    let inline append2 (x:'T) y :'T = (HelperType <*> Unchecked.defaultof<'T>) x y
    

    那么解决输出参数的意义何在?

    在这种情况下是没有意义的,但对于类型函数它会。

    【讨论】:

    • 让我把它讲一遍......所以第二个知道更多......所以它试图解决它,但不能这样失败......但不会将它推迟到调用站点?而第一个什么都不知道,所以不打扰....看起来很奇怪
    • 有办法解决吗?
    • 编译器就是这样写的。如果你告诉我你想达到什么目标,我可能会提出一些建议。
    • 所以原始附加的问题,这很好......如果有一个值要传递,但可以说我想要一个返回值的“零”函数或“身份”函数。 ...那么就没有要传递的值(我可能必须注释类型以强制推理)。
    • 看起来很奇怪的是,如果编译器尝试过但失败了,但随后注意到它是一个内联函数,然后将其留给调用站点,它就能够推断出类型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-07
    • 2014-04-14
    相关资源
    最近更新 更多