繁体   English   中英

无法推断(Eq a),将Eq添加到类型类

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM