Haskell编写关系传递闭包函数出现类型匹配错误求解
问题排查
- 第一类报错的核心原因是Haskell函数调用优先级规则。你在otherwise分支写的
relTrans remove_dups(rel ++ ...)会被Haskell解析为(relTrans remove_dups) (rel ++ ...),也就是给只接受1个参数的relTrans传递了2个参数(第一个是remove_dups函数本身,第二个是括号内的列表),和你预期的relTrans (remove_dups (rel ++ ...))完全不一致。这就是两条报错共同的触发点:编译器认为你给relTrans多传了参数,同时remove_dups没有拿到它需要的列表参数。 - 第二个隐藏错误:
remove_dups定义中使用了大写的XS,Haskell中变量名必须以小写字母开头,大写开头的标识符会被识别为类型/数据构造器,编译无法通过。 - 第三个类型错误:
remove_dups和removeElem的类型签名缺少Eq约束。你在removeElem中使用了==比较元素相等性,必须要求元素类型实现Eq类型类,否则无法通过类型检查。
修正后的完整代码
relComp :: [(Integer, Integer)] -> [(Integer, Integer)] -> [(Integer, Integer)] relComp r1 r2 = [(a,c) | (a,k1)<-r1, (k2,c)<-r2, k1 == k2] removeElem :: Eq a => a -> [a] -> [a] removeElem n [] = [] removeElem n (m:zs) = if n == m then removeElem n zs else m : removeElem n zs remove_dups :: Eq a => [a] -> [a] remove_dups [] = [] remove_dups (x:xs) = x : remove_dups (removeElem x xs) relTrans :: [(Integer, Integer)] -> [(Integer, Integer)] relTrans rel | rel == remove_dups (rel ++ relComp (remove_dups rel) (remove_dups rel)) = rel | otherwise = relTrans (remove_dups (rel ++ relComp (remove_dups rel) (remove_dups rel)))
内容的提问来源于stack exchange,提问作者user202004
相关产品推荐
相关产品推荐

