[英]Could not deduce (Eq a), adding Eq to typeclass
我是Haskell的新手,在尝试编译Frag时遇到了这个bug。
src/AFRPVectorSpace.hs:51:25:
Could not deduce (Eq a) arising from a use of `/='
from the context (VectorSpace v a)
bound by the class declaration for `VectorSpace'
at src/AFRPVectorSpace.hs:(32,1)-(53,23)
Possible fix:
add (Eq a) to the context of
the class declaration for `VectorSpace'
In the expression: nv /= 0
In the expression:
if nv /= 0 then v ^/ nv else error "normalize: zero vector"
In an equation for `normalize':
normalize v
= if nv /= 0 then v ^/ nv else error "normalize: zero vector"
where
nv = norm v
相关代码:
class Floating a => VectorSpace v a | v -> a where
zeroVector :: v
(*^) :: a -> v -> v
(^/) :: v -> a -> v
negateVector :: v -> v
(^+^) :: v -> v -> v
(^-^) :: v -> v -> v
dot :: v -> v -> a
norm :: v -> a
normalize :: v -> v
v ^/ a = (1/a) *^ v
negateVector v = (-1) *^ v
v1 ^-^ _ = v1 ^+^ v1 -- (negateVector v2)
norm v = sqrt (v `dot` v)
normalize v = if nv /= 0 then v ^/ nv else error "normalize: zero vector"
where
nv = norm v
我的第一个猜测是我需要添加一个Deriving Eq
或类似的东西,但我不确定我到底需要做什么。
我猜你需要class (Eq a,Floating a) => VectorSpace va | v -> a
class (Eq a,Floating a) => VectorSpace va | v -> a
,如果你想使用/=
为a
在您的默认实现。
第二种方法是从类中删除normalize
并使其成为普通函数。
第三种方法是将约束添加到normalize
的类型,使其成为Eq a => v -> v
。
在ghc 7.4.1之前, Num a
类具有Eq a
约束,因此任何Num a
也具有Eq a
。 Floating a
具有约束Num a
,因此Floating a
任何东西也是Eq a
。
但是,这改变了7.4.1,其中Eq a
约束(以及Show a
constraint)从Num
类中删除。 这就是代码不再起作用的原因。
因此问题的解决方案正是aleator给出的:将Eq a
约束显式添加到VectorSpace
类。
或者,您可能希望下载旧版本的ghc(例如,基于wiki备注的6.8)。 该版本应该编译程序而不做任何更改。 然后,如果您愿意,可以更新代码以使其与更新版本的ghc一起使用。
这不是你的问题的答案(已经回答了),但由于将代码块粘贴到评论中并不容易,我将其添加为“答案”。
您可能更喜欢使用类型系列而不是函数依赖项。 类型系列允许您使用功能依赖项执行所有操作,还可以执行更多操作。 这是使用类型族编写代码的一种方法。 它看起来与你的原始代码非常相似,只是你的类型变量a
已被替换为类型函数 Metric v
的“调用”(我能想到的最好的名字。)
{-# LANGUAGE TypeFamilies, FlexibleContexts #-}
class Floating (Metric v) => VectorSpace v where
type Metric v
zeroVector :: v
(*^) :: Metric v -> v -> v
(^/) :: v -> Metric v -> v
negateVector :: v -> v
(^+^) :: v -> v -> v
(^-^) :: v -> v -> v
dot :: v -> v -> Metric v
norm :: v -> Metric v
normalize :: Eq (Metric v) => v -> v
v ^/ a = (1/a) *^ v
negateVector v = (-1) *^ v
v1 ^-^ _ = v1 ^+^ v1 -- (negateVector v2)
norm v = sqrt (v `dot` v)
normalize v = if nv /= 0 then v ^/ nv else error "normalize: zero vector"
where
nv = norm v
以下是一些有用的链接:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.