Haskell 与“Eq”等价的类型族?
显示: 正如我不完全理解的,这张幻灯片展示了两种实现Haskell 与“Eq”等价的类型族?,haskell,Haskell,显示: 正如我不完全理解的,这张幻灯片展示了两种实现Eq:通过类型类或类型族 我熟悉类型类,因此实现了MyEq: class MyEq a where eq :: a -> a -> Bool 但是,当我试图定义类型系列版本时,它未能编译: data Defined = Yes | No type family IsEq (a :: *) :: Defined 由于: TypeEq.hs:30:30: error: • Type constructo
Eq
:通过类型类或类型族
我熟悉类型类,因此实现了MyEq
:
class MyEq a where
eq :: a -> a -> Bool
但是,当我试图定义类型系列
版本时,它未能编译:
data Defined = Yes | No
type family IsEq (a :: *) :: Defined
由于:
TypeEq.hs:30:30: error:
• Type constructor ‘Defined’ cannot be used here
(Perhaps you intended to use DataKinds)
• In the kind ‘Defined’
请解释如何实现Eq
type类的type系列
版本。
另外,请展示这样一个
类型族
实例的实现(如果这是一个正确的词)。尝试添加数据种类
作为语言扩展名(即在文件顶部的“language”pragma下),如错误消息所示
我没有看演讲,但是iiuc,Defined
只是Bool
,其中Yes
是True
。因此,如果您启用数据种类,您可以只使用IsEq a~'True
(True之前的撇号表示“这是一种类型”)
一些背景:此扩展所做的是将任何代数数据类型(即使用数据
声明,但不是GADTs
,iiuc)的每个值“提升”为自己的类型;然后将每个类型提升为自己的类型(Haskell中的“种类”是“类型的类型”),即不是“种类*”(发音为“种类星形”),这是运行时存在的正常Haskell值的类型
顺便说一句:
[Bool]::*
表示“留置权列表是一种类型”。而[]::*->*
意味着列表的类型构造函数具有“类型到类型”的类型,即“一旦给列表一个类型,就可以得到一个类型” 这有点整洁,很高兴偶然发现了这一点。对于感兴趣的人来说,这是幻灯片和纸张。这是需要一些语言扩展的常见情况
{-# LANGUAGE DataKinds, TypeFamilies, TypeOperators, ConstraintKinds #-}
data Defined = Yes | No
type family IsEq (a :: *) :: Defined
type Eq a = IsEq a ~ Yes
然后,这个的“实现”是这样的实例
type instance IsEq () = Yes -- '()' is an instance of 'Eq'
type instance IsEq Int = Yes -- 'Int' is an instance of 'Eq'
type instance IsEq [a] = IsEq a -- '[a]' is an instance of 'Eq' is 'a' is
您可以在GHCi“试用”它们:
ghci> :kind! IsEq [Int]
IsEq [Int] :: Defined
= Yes
但是纸和幻灯片并没有太多关于实际提供相等功能的担心。(它提到将其存储在Yes
字段中)。那么,如果它甚至还没有准备好提供类方法,那么为什么这很有趣呢?因为
- 与重叠类相比,它提供了更好的机制
- 回溯搜索比使用TypeClass更容易
- 它可以使用漂亮的错误消息提前失败(编码为
构造函数中的字段)No
:种类!IsEq[Int]
是一种类型级计算。这是否意味着对实际值(例如,[1,2,3]
)应用IsEq
没有意义?@KevinMeredithIsEq a~是
是一个等式约束-仅当LHS和RHS相等时才成立。这里,我们要定义约束Eq a
,以保持iffIsEq a
和Yes
相等。是的,将IsEq
应用于像[1,2,3]
这样的实际值毫无意义-IsEq
是一个类型族(一个有限的类型级别函数),而不是一个(值级别)函数。