筛选列表列表

发布于 2024-12-11 09:03:08 字数 850 浏览 0 评论 0原文

我对 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

末が日狂欢 2024-12-18 09:03:08

numLongChains 的类型签名可能不正确。根据您想要执行的操作,需要以下其中一项:

  • 您只是想对这些链进行计数,您的函数 numLongChains 显然应返回一个数字,将第一行更改为 length $ filter isLong (map chain [1..100]) 和类型 Int
  • 您想要返回长链的长度列表。在这种情况下,类型签名很好,但您需要返回一个长度。我建议您在过滤之前计算长度并对其进行过滤。函数的主体变为 filter (>15) (map (length . chain) [1..100])
  • 您想要返回所有长度超过 15 个字符的链。只需将签名更改为 [[Int]]Int 的链(列表)列表)就可以了。

The type signature of numLongChains is probably not correct. Depending on what you want to do, one of the following is needed:

  • You simply want to count those chains, your function numLongChains obviously shall return a number, change the first line to length $ filter isLong (map chain [1..100]) and the type to Int
  • You want to return a list of lengths of the long chains. In this case, the type signature is fine, but you need to return a length. I'd suggest you, the calculate the length before filtering and filter on it. The function's body becomes filter (>15) (map (length . chain) [1..100]).
  • You want to return all chains that are longer than 15 chars. Just change the signature to [[Int]] (A list of chains (lists) of Ints) and you're fine.
浅浅淡淡 2024-12-18 09:03:08

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 expecting Int -> 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 takes Ints and returns Bools (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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文