过滤列表清单
我对Haskell很新,只是开始学习它。 我正在使用“学习你一个伟大的好事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])
可以采取什么问题吗?
numLongChains
的型号签名可能不正确。根据你想要做什么,下面的一个需要:
- 你只是想算的锁链,你的函数
numLongChains
显然应返回一个数字,改变第一行length $ filter isLong (map chain [1..100])
和类型Int
- 您想要返回长链长度的列表。在这种情况下,类型签名很好,但你需要返回一个长度。我建议你,在过滤和筛选之前计算长度。该功能的主体变成了
filter (>15) (map (length . chain) [1..100])
。 - 您想返回所有长度超过15个字符的链。只需将签名更改为
[[Int]]
(链表(列表)Int
s),您就可以了。
FUZxxl是正确的。您将要将您的功能的类型签名更改为[[Int]]
。由于您正在筛选列表并只选择足够长的列表,因此您将返回列表列表。
关于阅读Haskell编译时调试器/错误的一个注意事项。这个错误看起来很奇怪。它说你有[a0] -> Bool
但你期待Int -> Bool
。这是因为类型检查器假定,从您的numLongChains函数的签名中,您将需要一个筛选函数来检查Ints并返回可接受的列表。对列表进行过滤并获取[Int]的唯一方法是获取一个需要Int
s并返回Bool
s (Int -> Bool)
的函数。相反,它会看到一个检查长度的函数。长度需要一个列表,所以它猜测你写了一个函数来检查列表。 ([a0] -> Bool)
。有时候,检查者并不像你期望的那么友善,但是如果你看起来足够努力,你会看到10次中有9次,难以辨认的错误是诸如假设的结果。
Erik,也谢谢你,但我所知道的是,现在对我来说太难了:)而且关于我从命令式语言中知道的隐式转换的邪恶 – dmitry
谢谢!真的是我的错,用[[Int]]解决了问题 – dmitry
@dmitry请接受这个答案来帮助别人。只需点击答案评分下方的绿色勾号即可。 – fuz