Ord:未找到 Data.Eq.Eq 类型的 class 实例(扩展 a0)。 PureScript by Example 书,第 6 章
Ord: No type class instance was found for Data.Eq.Eq (Extended a0). PureScript by Example book, Chapter 6
我对 Haskell/Purescript 很陌生,目前正在学习 PureScript by Example book。
在 chapter 6 about type classes, exercise 4 中有以下任务:
(Medium) Given any type a
with an instance of Ord
, we can add a new "infinite" value which is greater than any other value:
data Extended a = Finite a | Infinite
Write an Ord
instance for Extended a
which reuses the Ord
instance for a
.
这是我的尝试:
instance ordExtended :: Ord a => Ord (Extended a) where
compare Infinite Infinite = EQ
compare Infinite _ = GT
compare _ Infinite = LT
compare (Finite f1) (Finite f2) = compare f1 f2
不幸的是,代码触发了一个错误:
No type class instance was found for
Data.Eq.Eq (Extended a0)
while checking that expression #dict Eq
has type { eq :: Extended a0 -> Extended a0 -> Boolean
}
in value declaration ordExtended
where a0 is a rigid type variable
bound at (line 0, column 0 - line 0, column 0)
PureScript(NoInstanceFound)
我不太明白错误信息:
expression #dict Eq
是什么意思?我的代码里没有dict
.
- 什么是刚性类型变量?
- 错误似乎使用了不同的标识符,例如
a0
(为什么?我假设是 a
)
在我的书中,Eq
类型 class 实例应该通过实现 Ord
来涵盖,因为 Ord
扩展了 Eq
.
错误的关键部分在开头:
No type class instance was found for
Data.Eq.Eq (Extended a0)
这里是Ord
的定义:
class Eq a <= Ord a where
compare :: a -> a -> Ordering
这实际上是superclass语法,说你需要一个Eq
实例才能有一个Ord
实例。因此,您可以通过创建 Eq
实例来修复错误:
instance eqExtended :: Eq a => Eq (Extended a) where
eq Infinite Infinite = true
eq (Finite f1) (Finite f2) = eq f1 f2
eq _ _ = false
instance ordExtended :: Ord a => Ord (Extended a) where
compare Infinite Infinite = EQ
compare Infinite _ = GT
compare _ Infinite = LT
compare (Finite f1) (Finite f2) = compare f1 f2
至于为什么使用 a0
,似乎纯脚本编译器只是喜欢在类型变量之后添加数字,可能是为了减少模糊性或允许作用域类型变量。您可以 read about rigid type variables here(它们基本上是无法更改以适应约束的变量)。
我对 Haskell/Purescript 很陌生,目前正在学习 PureScript by Example book。
在 chapter 6 about type classes, exercise 4 中有以下任务:
这是我的尝试:(Medium) Given any type
a
with an instance ofOrd
, we can add a new "infinite" value which is greater than any other value:data Extended a = Finite a | Infinite
Write an
Ord
instance forExtended a
which reuses theOrd
instance fora
.
instance ordExtended :: Ord a => Ord (Extended a) where
compare Infinite Infinite = EQ
compare Infinite _ = GT
compare _ Infinite = LT
compare (Finite f1) (Finite f2) = compare f1 f2
不幸的是,代码触发了一个错误:
No type class instance was found for
Data.Eq.Eq (Extended a0)
while checking that expression #dict Eq has type { eq :: Extended a0 -> Extended a0 -> Boolean } in value declaration ordExtended
where a0 is a rigid type variable bound at (line 0, column 0 - line 0, column 0) PureScript(NoInstanceFound)
我不太明白错误信息:
expression #dict Eq
是什么意思?我的代码里没有dict
.- 什么是刚性类型变量?
- 错误似乎使用了不同的标识符,例如
a0
(为什么?我假设是a
)
在我的书中,Eq
类型 class 实例应该通过实现 Ord
来涵盖,因为 Ord
扩展了 Eq
.
错误的关键部分在开头:
No type class instance was found for
Data.Eq.Eq (Extended a0)
这里是Ord
的定义:
class Eq a <= Ord a where
compare :: a -> a -> Ordering
这实际上是superclass语法,说你需要一个Eq
实例才能有一个Ord
实例。因此,您可以通过创建 Eq
实例来修复错误:
instance eqExtended :: Eq a => Eq (Extended a) where
eq Infinite Infinite = true
eq (Finite f1) (Finite f2) = eq f1 f2
eq _ _ = false
instance ordExtended :: Ord a => Ord (Extended a) where
compare Infinite Infinite = EQ
compare Infinite _ = GT
compare _ Infinite = LT
compare (Finite f1) (Finite f2) = compare f1 f2
至于为什么使用 a0
,似乎纯脚本编译器只是喜欢在类型变量之后添加数字,可能是为了减少模糊性或允许作用域类型变量。您可以 read about rigid type variables here(它们基本上是无法更改以适应约束的变量)。