特别是,我想为此类型编写扩展方法:
type Frame<'TRowKey, string when 'TRowKey : equality> with
member frame.someMethod =
// code
使用该代码,我收到此错误:
类型名称中的意外标识符。预期的中缀运算符,引号或其他标记。
将string
替换为String
会得到相同的结果。
原始类型是Deedle库中的Frame<'TRowKey, 'TColumnKey (requires equality and equality)>
。
答案 0 :(得分:5)
@Gustavo彻底解答了如何使用扩展方法。但是如果你没有特别强烈的理由将它作为一种扩展方法(比如C#interop),你可能会选择一个简单的函数:
type Frame<'row, 'col> = { row: 'row; col: 'col }
module Frame =
let restricted (frame: Frame<'row, string>) = frame
Frame.restricted { row = 3; col = "test" } // compiles
Frame.restricted { row = 3; col = 5 } // doesn't
我在编写F#时只考虑更简洁的方法 - 只有代码 - 当它们作为类型的内在部分不具有意义时,let-bound函数优于方法,并且从属性中减少噪音。
答案 1 :(得分:2)
我没有Deedle来测试这段代码但你应该使用.NET扩展方法:
open System
[<Runtime.CompilerServices.Extension>]
module Extensions =
[<Runtime.CompilerServices.Extension>]
let someMethod<'TRowKey when 'TRowKey : equality> (frame :Frame<'TRowKey, string>) = // body
这与scrwtp称之为“惯用方式”的方式相同。 (我不想讨论有关idomaticity的问题)但同时它也可以作为扩展方法从C#开始。
如果要从F#和扩展名中使用它,必须将其声明为类型:
[<Runtime.CompilerServices.Extension>]
type Extensions =
[<Runtime.CompilerServices.Extension>]
static member someMethod<'TRowKey when 'TRowKey : equality> (frame :Frame<'TRowKey, string>) = // body
所以现在你可以输入row.
,如果第二个参数是一个字符串,intellisense将只显示扩展名。