筛选列表列表
我对 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
所以现在,我不想计数这些链,但返回这些链的过滤列表。 但现在编译时出现错误:
无法将预期类型“Int”与实际类型“[a0]”匹配 预期类型:Int ->布尔 实际类型:[a0] ->布尔 在`filter'的第一个参数中,即`isLong' 表达式中:filter isLong(map chain [1 .. 100])
可能是什么问题?
I'm very new with Haskell, only starting to learn it.
I'm using "Learn You a Haskell for Great Good!" tutorial for start, and saw example of solving "3n+1" problem:
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
so, numLongChains counts all chains that longer 15 steps, for all numbers from 1 to 100.
Now, I wanna my own:
numLongChains' :: [Int]
numLongChains' = filter isLong (map chain [1..100])
where isLong xs = length xs > 15
so now, I wanna not to count these chains, but return filtered list with these chains.
But now I get error when compiling:
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])
What can be the problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
numLongChains
的类型签名可能不正确。根据您想要执行的操作,需要以下其中一项:Int
filter (>15) (map (length . chain) [1..100])
。[[Int]]
(Int
的链(列表)列表)就可以了。The type signature of
numLongChains
is probably not correct. Depending on what you want to do, one of the following is needed:numLongChains
obviously shall return a number, change the first line tolength $ filter isLong (map chain [1..100])
and the type toInt
filter (>15) (map (length . chain) [1..100])
.[[Int]]
(A list of chains (lists) ofInt
s) and you're fine.FUZxxl 是对的。您需要将函数的类型签名更改为
[[Int]]
。当您过滤列表列表并仅选择足够长的列表时,您将返回列表列表。关于阅读 Haskell 编译时调试器/错误的一点说明。这个错误可能看起来很奇怪。它说你有
[a0] -> Bool
但你期待的是Int ->布尔。这是因为类型检查器假设,根据 numLongChains 函数的签名,您将需要一个过滤器函数来检查 Int 并返回可接受的列表。过滤列表并返回 [Int] 的唯一方法是使用一个接受
Int
并返回Bool
的函数(Int -> Bool )
。相反,它看到一个检查长度的函数。 Length 接受一个列表,因此它猜测您编写了一个检查列表的函数。([a0] -> Bool)
。有时,检查器并不像您希望的那样友好,但如果您足够仔细,您会发现十分之九的难以破译的错误是由此类假设造成的。FUZxxl is right. You are going to want to change the type signature of your function to
[[Int]]
. As you are filtering a list of lists and only selecting the ones that are sufficiently long, you will have returned a lists of lists.One note about reading Haskell compile-time debugger/errors. This error may seem strange. It says you had
[a0] -> Bool
but you were expectingInt -> Bool
. This is because that the type checker assumes that, from the signature of your numLongChains' function, you are going to need a filter function that checks Ints and returns a list of acceptable ones. The only way to filter over a list and get [Int] back is to have a function that takesInt
s and returnsBool
s(Int -> Bool)
. Instead, it sees a function that checks length. Length takes a list, so it guesses that you wrote a function that checks lists.([a0] -> Bool)
. Sometimes, the checker is not as friendly as you would like it to be but if you look hard enough, you will see that 9 times out of 10, a hard to decipher error is the result of such as assumptions.