Haskell报错:No instance for (Eq Movimento) 问题求助
错误原因分析与修复
问题代码
data Movimento = Norte | Sul | Este | Oeste deriving Show myhasLoops :: Eq Movimento => (Int,Int) -> [Movimento] -> Bool myhasLoops (x,y) (h:t) | auxxx (x,y) (h:t) 0 == 0 = True | otherwise = False auxxx :: Eq Movimento => (Int,Int) -> [Movimento] -> Int -> Int auxxx (x,y) (h:t) acc | h == Norte = 1 + auxxx (x,y) t (acc+1) | h == Sul = (-1) + auxxx (x,y) t (acc-1) | h == Este = 1 + auxxx (x,y) t (acc+1) | h == Oeste = (-1) + auxxx (x,y) t (acc-1) | otherwise = acc
触发的错误
<interactive>:125:1: error: * No instance for (Eq Movimento) arising from a use of `myhasLoops' * In the expression: myhasLoops (1, 2) [Norte, Sul] In an equation for `it': it = myhasLoops (1, 2) [Norte, Sul]
错误原因
Movimento类型仅派生了Show实例,未派生Eq实例,但myhasLoops和auxxx的类型签名都明确要求Eq Movimento约束。auxxx内部使用==运算符比较Movimento构造器(如h == Norte),该操作必须依赖Eq类型类的实例支持,Haskell不会自动为自定义类型生成Eq实例,需显式通过deriving声明。
修复方案
在Movimento的类型定义中添加Eq到派生列表:
data Movimento = Norte | Sul | Este | Oeste deriving (Show, Eq)
另外需注意两处潜在问题:
myhasLoops未处理空列表输入,传入空列表会触发模式匹配失败auxxx逻辑设计偏离目标:当前仅简单累加数值,未跟踪坐标变化,无法正确判断是否回到初始位置(形成循环),若目标是检测移动是否回到起点,需修改函数以更新坐标而非累加无关数值。
内容的提问来源于stack exchange,提问作者Pedro Augusto
相关产品推荐
相关产品推荐

