大多数编程语言都有一些基于类型在编译时选择实现的方法。函数重载是执行此操作的常用方法。使用模板(在C ++中或可能带有约束的D)是另一种选择。
但是在F#中,我无法在不使用类方法的情况下找到如何做到这一点,从而失去了一些好的属性,如currying。
let f (a:int) =
提供Duplicate definition of 'f'
F#有statically resolved type parameters,但我不知道如何使用它..
let f (a:^T) =
match T with
The value or constructor of T is not defined
match T
let f (a:^T) =
match a with
| :> int as i ->
提供Unexpected symbol ':>' in expression
let f (a:^T) =
match ^a with
| :> int as i ->
提供Unexpected infix operator in expression
答案 0 :(得分:4)
如果你想编写一个对不同类型行为不同的函数并且是一个普通的F#函数,那么静态成员约束就可以让你这样做。但是,如果您想编写惯用的F#代码,那么还有其他选项:
Here is a good example展示如何使用静态成员约束来执行此操作
F#集合为每种类型使用不同的模块,因此有Array.map
,List.map
,Seq.map
等。这是功能性F#库的惯用样式。
FSharpChart是使用重载方法的库的示例。请注意,您可以使用静态方法,因此您可以编写Chart.Line [ ... ]
并选择正确的重载。
如果您要编写通用数字代码,请I recently wrote a tutorial that covers this topic。
所以,在使用静态约束之前我会有点小心 - 它不完全是惯用的(例如在标准库中不常用),因此可能会引起一些混淆。但它非常强大,当然也很有用。
关键是,只需遵循在其他语言中运行良好的模式,可能无法在F#中获得最佳效果。如果你能提供一个具体的例子来说明你要做的事情,那么你可能会得到更好的结果。