什么是最接近哈斯克尔GADTs和类型类在F#?(What's the closest thi

2019-07-03 16:35发布

F#是OOP的ML。 什么是涉及到哈斯克尔广义代数的数据类型和类型类最接近?

Answer 1:

答案取决于你想解决什么问题。 F#没有类型类和GADTs,所以没有直接映射。 然而,F#有,你会用它来解决,你通常在Haskell使用GADTs和类型类解决问题的各种机制:

  • 如果你想表示对象的结构,并能够与不同的行为增加新的具体实现,那么你可以经常使用标准的面向对象和接口。

  • 如果你想编写通用的数字代码,您可以使用静态成员的限制( 这里有一个例子 ),这可能是技术上键入类最接近的机制。

  • 如果你想写更先进的通用代码(如万能打印机或解析器),那么你可以经常使用的功能强大的F#运行时反射能力。

  • 如果你需要通过一组功能(执行的代码所需的各种子操作)参数化代码,那么你可以通过围绕界面@pad显示的实现。

还有一种方式来仿效F#Haskell的类型类 ,但是这通常不是一个地道的F#的解决方案,因为F#编程风格从哈斯克尔风格不同的多种方式。 一个相当标准的使用,这是定义运算符重载,但(见本SO回答 )。

在元级,询问什么是相当于aother语言往往会导致混乱的讨论功能X,因为X可以用来解决问题的A,B,C中的一种语言,而另一种语言可以提供不同的功能来解决同样的问题(或者有些问题可能不存在的话)。



Answer 2:

在F#中,你经常使用的接口 ,并继承了这些目的。

对于实施例起见,这里是使用接口和一个简单的类型类对象的表达式 :

/// Typeclass
type MathOps<'T> =
    abstract member Add : 'T -> 'T -> 'T
    abstract member Mul : 'T -> 'T -> 'T

/// An instance for int
let mathInt = 
    { new MathOps<int> with
       member __.Add x y = x + y
       member __.Mul x y = x * y }

/// An instance for float
let mathFloat = 
    { new MathOps<float> with
       member __.Add x y = x + y
       member __.Mul x y = x * y }

let XtimesYplusZ (ops: MathOps<'T>) x y z =
    ops.Add (ops.Mul x y) z

printfn "%d" (XtimesYplusZ mathInt 3 4 1)
printfn "%f" (XtimesYplusZ mathFloat 3.0 4.0 1.0)

它可能看起来不很漂亮,但它是F#-ish办法做到这一点。 对于使用一个字典中的操作更哈斯克尔样的解决方案,你可以看看这个漂亮的答案 。



文章来源: What's the closest thing to Haskell GADTs and typeclasses in F#?