什么';F#中最接近Haskell GADTs和TypeClass的是什么?
F#是一个带有OOP的ML。最接近Haskell广义代数数据类型和类型类的是什么?答案取决于您试图解决的问题。F#没有类型类和GADT,因此没有直接映射。但是,F#有各种机制,您可以使用它们来解决通常在Haskell中使用GADT和TypeClass解决的问题:什么';F#中最接近Haskell GADTs和TypeClass的是什么?,f#,typeclass,gadt,F#,Typeclass,Gadt,F#是一个带有OOP的ML。最接近Haskell广义代数数据类型和类型类的是什么?答案取决于您试图解决的问题。F#没有类型类和GADT,因此没有直接映射。但是,F#有各种机制,您可以使用它们来解决通常在Haskell中使用GADT和TypeClass解决的问题: 如果您希望表示对象结构并能够添加具有不同行为的新的具体实现,那么您可以经常使用标准的OO和接口 如果要编写泛型数字代码,可以使用静态成员约束(),从技术上讲,这可能是最接近类型类的机制 如果您想编写更高级的通用代码(如通用打印机或解析
- 如果您希望表示对象结构并能够添加具有不同行为的新的具体实现,那么您可以经常使用标准的OO和接口
- 如果要编写泛型数字代码,可以使用静态成员约束(),从技术上讲,这可能是最接近类型类的机制
- 如果您想编写更高级的通用代码(如通用打印机或解析器),则可以经常使用这些功能
- 如果需要通过一组函数(执行代码所需的各种子操作)对代码进行参数化,则可以传递接口的实现,如@pad所示
///Typeclass
键入MathOps'T->'T
抽象成员Mul:'T->'T->'T
///int的一个实例
设mathInt=
{新的MathOps与
成员_uu。添加x y=x+y
成员_uu.Mul x y=x*y}
///float的一个例子
设mathFloat=
{新的MathOps与
成员_uu。添加x y=x+y
成员_uu.Mul x y=x*y}
让XtimesYplusZ(ops:mathopsts)这是一个误导性的例子,因为对于数字代码,您只需编写let inline XtimesYplusZ x y z=(x*y)+z
和XtimesYplusZ 3 4 1
和XtimesYplusZ 3.0 4.0 1.0
将起作用。但当然,在不同的场景中,基于您演示的样式的代码将是通过操作对此类参数化建模的好方法。我想这就是我所说的不同pr有不同的方法的意思Haskell中的类型类解决了一些问题。是的,我很难找到一个好的例子。我想演示的只是编码风格;它与数字代码无关。我不明白。你只是在使用泛型。@LeoCavalcante,这里有一篇Haskell文章解释了这个想法:基本上你可以使用签名(Monad m)=>[MA]来使用类型类->m[a]并将其转换为常规值签名MonadWitness m->[ma]->m[a],并完全绕过类型级编程,只要您愿意显式传递见证。
/// 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)