【问题标题】:F# active pattern as non-static memberF# 活动模式作为非静态成员
【发布时间】:2010-12-22 06:43:23
【问题描述】:

我不确定是否允许非静态公共成员活动模式,但您可以在编译器不抱怨的情况下定义它们。如果它们被允许,匹配一个的语法是什么?编译器给了我 FooBar2.doSomething 中 Foo 的类型不匹配。期望 'a -> Choice<'b,'c> 给定 'a -> 'd -> Choice<unit,unit>

// No error in this class, static works great
type FooBar() = 
    static member (|Foo|Bar|) (x, y) =
        match x = y with
        | true -> Foo
        | false -> Bar

    member x.doSomething y =
        match x, y with
        | Foo -> ()
        | Bar -> ()

type FooBar2() = 
    member x.(|Foo|Bar|) y =
        match x = y with
        | true -> Foo
        | false -> Bar

    // compiler error on "Foo"    
    member x.doSomething y =
        match y with
        | Foo -> ()
        | Bar -> ()

【问题讨论】:

    标签: f# member active-pattern


    【解决方案1】:

    成员识别器似乎自 1.9.9.9 版起就已失效。即使是静态成员。我认为这是一种耻辱,因为它允许识别器重载。我可以有一个用于 Type、MemberInfo 等的“名称”识别器。现在我需要一个“Type_Name”。 'Member_Name' 等以避免命名冲突。只是“名称”更好。

    【讨论】:

      【解决方案2】:

      不应将活动模式用作成员。这些完全编译的事实是我们将修复的编译器错误(感谢报告:))。使用本地或模块绑定的“let”来定义活动模式。

      【讨论】:

      • 嗯,至少没有静态版本让我不得不使用模块,而不仅仅是命名空间。我对此唯一担心的是两者之间的名称/行为相同。这可能会导致重复命名。我宁愿将我所有的网络代码保留在命名空间 Network 中,而不是有一个模块 Network,我相信 CLR 会变成一个全静态类。所以我最终会得到类似 MyApp.Network.ModuleName.Identifier
      【解决方案3】:

      我对这不起作用并不感到惊讶,而且我看不到对实例活动模式的自然语义解释。当您看到Foo 模式时,您如何知道要使用哪个实例?对于FooBar 情况,您能否有不同的实例(因此是不完整的模式匹配)?这里的问题似乎没有一个优雅的解决方案。老实说,我很惊讶即使是静态案例也能正常工作,而且我在规范中没有看到任何内容将活动模式定义为任何类型的成员。

      【讨论】:

        猜你喜欢
        • 2011-01-24
        • 2011-05-31
        • 1970-01-01
        • 1970-01-01
        • 2012-04-13
        • 1970-01-01
        • 2017-10-16
        • 1970-01-01
        • 2012-07-28
        相关资源
        最近更新 更多