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#?