Haskell 哈斯克尔的8个皇后,未知错误?

Haskell 哈斯克尔的8个皇后,未知错误?,haskell,haskell-platform,Haskell,Haskell Platform,我试图在Haskell中解决8 queens问题,不使用任何高级函数,只使用基本知识。我只走了这么远,但我犯了一个我无法理解的错误。 守则: queens = [[x1,x2,x3,x4,x5,x6,x7,x8] | x1<-[1..8], x2<-[1..8], x3<-[1..8], x4<-[1..8], x5<-[1..8], x6<-[1..8],

我试图在Haskell中解决8 queens问题,不使用任何高级函数,只使用基本知识。我只走了这么远,但我犯了一个我无法理解的错误。 守则:

queens = [[x1,x2,x3,x4,x5,x6,x7,x8] | x1<-[1..8], x2<-[1..8],
                          x3<-[1..8], x4<-[1..8], x5<-[1..8],
                          x6<-[1..8], x7<-[1..8], x8<-[1..8],
                          safeH [x2,x3,x4,x5,x6,x7,x8] x1]
safeH xs e = if length xs == 1 then head xs 
                 else e /= safeH (tail xs) (head xs)
错误消息是:

y.hs:1:42:
    No instance for (Num Bool) arising from the literal `1'
    Possible fix: add an instance declaration for (Num Bool)
    In the expression: 1
    In the expression: [1 .. 8]
    In a stmt of a list comprehension: x1 <- [1 .. 8]
[1 of 1] Compiling Main             ( y.hs, interpreted )
Failed, modules loaded: none.
罪魁祸首是

                      .........
                      safeH [x2,x3,x4,x5,x6,x7,x8] x1]
safeH xs e = if length xs == 1 then head xs 
                 else e /= safeH (tail xs) (head xs)
具体来说,

                 else e /= safeH (tail xs) (head xs)
因为e==x1。因此,一方面,safeH返回Bool,作为列表理解中的测试。你把它的结果和x1比较一下。也就是1,除此之外,x1A。即,其具体类型必须属于Num type类。由于这里的具体类型也被确定为Bool,这意味着Bool必须属于Num type类,这样代码才能进行类型检查。因此,需要寻找Num Bool的实例。

如果。。。然后其他的safeH中的表达式类型不正确:

safeH l e = if length l == 1 then head l 
            else e /= safeH(tail l)(head l)
then分支错误地返回了数字类型,而else分支返回的是布尔类型Bool,我认为这是您想要的

您应该将类型签名添加到所有顶级函数中,作为记录代码功能、组织想法和使错误易于理解的一种方式;这里的错误消息是不必要的混淆,因为GHC推断您的代码正在从第一个分支返回Num类型的东西,所以当第二个分支返回Bool时,GHC抱怨错误的东西:Bool类型没有Num实例

您还应该阅读列表中的内容,并查看并思考为什么它不是实现您的功能的最佳方式

因此,不要使用长度和头部,而是从以下框架开始:

safeH :: [Int] -> Int -> Bool
safeH [n]    e = -- the case for a 1-length list
safeH (n:ns) e = -- ???

当某项功能正常工作时,请尝试重新定义它,其中基本情况是空列表[]。

safeH应该是什么类型?目前有两种可能:safeH::[Int]->Int->Int-then或safeH::[Int]->Int->Bool-else。因为您希望使用safeH进行筛选,所以您希望最后一个类型是Bool。然而,在这种情况下,e/=safeH tail l head l的右侧位置也是Bool,因此e也应该是Bool。如果你把这些类型想得再长一点,就容易多了。花点时间编写类型,然后编写函数。看起来您使用的是safeH,期望返回一个布尔值,但实际上您返回的是在代码中将l改为xs的数字头;这更像是哈斯凯尔风格,而l在某些字体中有时可读性较差将xs理解为x,复数形式,类似于axes;编辑您的问题并修复原始问题实际上不起作用,因为没有人的答案有任何意义,所以我还原了您上次编辑的内容。我已经编辑了代码,请您再看一看:@YaserJaradeh不,不,您不应该更改有问题的代码,因为它可能会使答案无效。但是,您的编辑将错误保留在适当的位置:您仍然在列表中比较测试调用中的x1 e,因此Num与safeH的结果。。。调用仍然是Bool的,因为/=的结果是Bool。@YaserJaradeh请不要再编辑您的问题;尝试修复您的代码,如果仍然必须,请提出新问题:超过9次编辑使问题社区成为wiki,您将不会因此获得任何声誉分数:问答哲学也是如此。这里的问题不是我如何编写此代码,而是我为什么会出现此错误?我已经编辑了此代码,请您再看一看: