我对Haskell很新,只是开始学习它。 我正在使用“让你学习哈斯克尔的伟大成就!”开始教程,看到解决“3n + 1”问题的例子:
chain :: (Integral a) => a -> [a]
chain 1 = [1]
chain n
| even n = n:chain (n `div` 2)
| odd n = n:chain (n*3 + 1)
numLongChains :: Int
numLongChains = length (filter isLong (map chain [1..100]))
where isLong xs = length xs > 15
所以,numLongChains计算所有超过15步的链,所有数字从1到100。
现在,我想要自己的:
numLongChains' :: [Int]
numLongChains' = filter isLong (map chain [1..100])
where isLong xs = length xs > 15
所以现在,我想不计算这些链,但返回带有这些链的过滤列表。 但是现在我在编译时遇到错误:
Couldn't match expected type `Int' with actual type `[a0]' Expected type: Int -> Bool Actual type: [a0] -> Bool In the first argument of `filter', namely `isLong' In the expression: filter isLong (map chain [1 .. 100])
可能是什么问题?
答案 0 :(得分:3)
numLongChains
的类型签名可能不正确。根据您的要求,需要满足以下条件之一:
numLongChains
显然会返回一个数字,将第一行更改为length $ filter isLong (map chain [1..100])
,将类型更改为Int
filter (>15) (map (length . chain) [1..100])
。[[Int]]
(Int
s的链(列表)列表)即可。答案 1 :(得分:1)
FUZxxl是对的。您将要将函数的类型签名更改为[[Int]]
。在过滤列表列表并仅选择足够长的列表时,您将返回列表列表。
关于读取Haskell编译时调试器/错误的一个注意事项。这个错误可能看起来很奇怪它说你有[a0] -> Bool
,但你期待Int -> Bool
。这是因为类型检查器假定,从numLongChains函数的签名中,您将需要一个过滤函数来检查Ints并返回一个可接受的列表。过滤列表并获取[Int]的唯一方法是使用Int
s并返回Bool
s (Int -> Bool)
的函数。相反,它会看到一个检查长度的函数。 Length需要一个列表,因此它猜测您编写了一个检查列表的函数。 ([a0] -> Bool)
。有时,检查器并不像你希望的那样友好,但是如果你看起来足够坚硬,你会看到10次中有9次,很难解读错误是假设的结果。