我怎样才能处理“发生检查:无法构造无限类型:a0 = [a0]”?

时间:2014-03-17 11:51:18

标签: haskell

代码:

myperms [] = [[]]
myperms xs = [a:ys| a<-xs, ys<-(delete a xs)]

我收到了这个错误:

project2.hs:66:15:
     Occurs check: cannot construct the infinite type: a0 = [a0]
     In the second argument of `(:)', namely `ys'
     In the expression: a : ys
     In the expression: [a : ys | a <- xs, ys <- (delete a xs)]

我无法想到这里的错误。有人可以向我解释如何处理这些情况,以免出错并编写更好的代码吗?提前谢谢。

2 个答案:

答案 0 :(得分:5)

@bheklilr已经解释了你的代码中的错误,但是你问:“有人可以向我解释如何处理这些情况以避免错误并编写更好的代码吗?”

我建议添加类型签名。

myperms :: [a] -> [[a]]
myperms [] = [[]]
myperms xs = [a:ys| a<-xs, ys<-(delete a xs)]

有时可以完全从代码中删除所有通用性,例如:

myperms :: [Int] -> [[Int]]
myperms [] = [[]]
myperms xs = [a:ys| a<-xs, ys<-(delete a xs)]

如果您仍然看不到该错误,请将其分解为较小的功能,并提供他们类型的签名:

genys:: Int->[Int]->[[Int]] -- I know this is wrong, that's the point
genys a xs=delete a xs

修复代码后,通常可以删除此脚手架。现在您将有一个更具体的错误,关于更具体的代码,您应该能够解决您的问题。

在编写实现之前编写类型签名是个好主意,它在早期就会发现很多错误。它还可以帮助澄清您对每个功能正在尝试做什么的思考。作为奖励,您可以在hoogle中查找您的类型签名,您可以使用已有的实现。

答案 1 :(得分:3)

问题在于你正在做什么

ys <- delete a xs

由于xs的类型为[a],而a的类型为a,因此delete a xs的类型为[a]。然后,您使用ysdelete a xs中的每个ys <-说“ys应该具有a类型,但您是然后尝试在其上使用a:,这意味着ys应该具有[a]类型。