在F#的编译时选择实现

时间:2013-08-21 19:28:41

标签: f# compile-time

大多数编程语言都有一些基于类型在编译时选择实现的方法。函数重载是执行此操作的常用方法。使用模板(在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

1 个答案:

答案 0 :(得分:4)

如果你想编写一个对不同类型行为不同的函数并且是一个普通的F#函数,那么静态成员约束就可以让你这样做。但是,如果您想编写惯用的F#代码,那么还有其他选项:

  • Here is a good example展示如何使用静态成员约束来执行此操作

  • F#集合为每种类型使用不同的模块,因此有Array.mapList.mapSeq.map等。这是功能性F#库的惯用样式。

  • FSharpChart是使用重载方法的库的示例。请注意,您可以使用静态方法,因此您可以编写Chart.Line [ ... ]并选择正确的重载。

  • 如果您要编写通用数字代码,请I recently wrote a tutorial that covers this topic

所以,在使用静态约束之前我会有点小心 - 它不完全是惯用的(例如在标准库中不常用),因此可能会引起一些混淆。但它非常强大,当然也很有用。

关键是,只需遵循在其他语言中运行良好的模式,可能无法在F#中获得最佳效果。如果你能提供一个具体的例子来说明你要做的事情,那么你可能会得到更好的结果。