我试图找出类型类和GADTS之间的区别,特别是在使用-XMultiParamTypeClasses扩展时。
两者似乎都有类似的用途:
class MyClass a b where
f :: a -> b -> Bool
instance MyClass String String where
f s1 s2 = ...
instance MyClass Int Int where
f i1 i2 = ...
data Gadt a where
F :: String -> String -> Bool
F2 :: Int -> Int -> Bool到目前为止,我真正看到的唯一不同之处是,GADT使函数类型接口具有灵活的number参数:
data Gadt a where
PassTwoArgs :: String -> String -> Gadt Bool
PassOneArgs :: String -> Gadt Bool
myFunction :: Gadt a -> a
myFunction (PassTwoArgs s1 s2) = ...
myFunction (PassOneArgs s1) = ...虽然使用类型类并不容易做到这一点。
是否有任何其他的区别或用例来使用一个而另一个?
发布于 2017-02-25 14:33:29
如果您有一个类,您可以在任何时候添加新实例。
如果使用GADT,则有一个永久固定的数据结构。在不更改原始定义的情况下,您永远不能向它添加新的案例。但是,正如您注意到的,它要灵活得多。
实际上,它们是为不同的用例设计的。类用于当您希望能够对许多不同的数据类型做一件事时,否则这些数据类型与彼此没有任何关系。(例如,您可以在Int和String上执行Int,但这些类型并不十分相似。)GADT用于当您想要一种类型时,但是它的一些类型参数告诉您一些关于它的事情。典型的示例是GADT在某种编程语言中表示表达式,您希望使用Haskell类型系统来强制执行另一种语言的类型系统。
什么类不像我们在面向对象编程中使用的“类”。请把所有这些想法都从你的脑子里拿出来。
发布于 2017-02-25 14:38:42
如果需要模式匹配,请使用(G)ADT。如果您需要第三方能够实现您的接口,请使用类型类型。
我的直觉是尽可能多地使用类型;如果我绝对需要模式匹配,那么我将使用(G)ADT。我通常不需要它。
https://stackoverflow.com/questions/42456698
复制相似问题