了解何时使用类型 类 或 GADT?
Understanding when to uses type classes or GADT's?
我试图找出类型 类 和 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 使函数类型接口具有灵活的数字参数:
data Gadt a where
PassTwoArgs :: String -> String -> Gadt Bool
PassOneArgs :: String -> Gadt Bool
myFunction :: Gadt a -> a
myFunction (PassTwoArgs s1 s2) = ...
myFunction (PassOneArgs s1) = ...
虽然使用 类 类型不容易做到这一点。
是否有任何其他差异或用例可以使用一个而不是另一个?
如果您有 class,您可以随时添加新实例。
如果您使用 GADT,您将拥有一个永远固定的数据结构。在不更改原始定义的情况下,您永远无法向其中添加新案例。但是,正如您所注意到的,它要灵活得多。
真的,它们适用于不同的用例。 类 适用于当您希望能够对许多不同的数据类型执行操作时,这些数据类型彼此之间没有任何关系。 (例如,您可以在 Int
和 String
上执行 (==)
,但这些类型不是很相似。)GADT 适用于您希望拥有 一种类型的情况,但它的一些类型参数告诉你一些关于它的信息。典型示例是 GADT 表示某种编程语言中的表达式,并且您想使用 Haskell 类型系统来强制执行 其他语言的 类型系统。
class与不同的是我们在面向对象编程中使用的"classes"。 ;-) 请把所有这些想法都赶出你的大脑。
如果需要模式匹配,请使用 (G)ADT。如果您需要第三方能够实现您的界面,请使用类型类。
我的直觉是尽可能多地使用类型类;如果我绝对需要模式匹配,那么我会使用 (G)ADT。我一般不需要。
我试图找出类型 类 和 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 使函数类型接口具有灵活的数字参数:
data Gadt a where
PassTwoArgs :: String -> String -> Gadt Bool
PassOneArgs :: String -> Gadt Bool
myFunction :: Gadt a -> a
myFunction (PassTwoArgs s1 s2) = ...
myFunction (PassOneArgs s1) = ...
虽然使用 类 类型不容易做到这一点。
是否有任何其他差异或用例可以使用一个而不是另一个?
如果您有 class,您可以随时添加新实例。
如果您使用 GADT,您将拥有一个永远固定的数据结构。在不更改原始定义的情况下,您永远无法向其中添加新案例。但是,正如您所注意到的,它要灵活得多。
真的,它们适用于不同的用例。 类 适用于当您希望能够对许多不同的数据类型执行操作时,这些数据类型彼此之间没有任何关系。 (例如,您可以在 Int
和 String
上执行 (==)
,但这些类型不是很相似。)GADT 适用于您希望拥有 一种类型的情况,但它的一些类型参数告诉你一些关于它的信息。典型示例是 GADT 表示某种编程语言中的表达式,并且您想使用 Haskell 类型系统来强制执行 其他语言的 类型系统。
class与不同的是我们在面向对象编程中使用的"classes"。 ;-) 请把所有这些想法都赶出你的大脑。
如果需要模式匹配,请使用 (G)ADT。如果您需要第三方能够实现您的界面,请使用类型类。
我的直觉是尽可能多地使用类型类;如果我绝对需要模式匹配,那么我会使用 (G)ADT。我一般不需要。