Haskell中的多个语句

con*_*sed 4 syntax haskell

你如何在haskell中有多个语句?

这是我正在尝试做的事情:给定一个像[a,b,c,d]这样的列表,返回所有其他元素,所以你得到[a,c].我可以看到解决方案,这是我到目前为止所拥有的:

fact (xs)   | length( xs ) `mod` 2  == 1 = head( xs )
    | otherwise = fact(tail( xs ))
Run Code Online (Sandbox Code Playgroud)

这在第一次工作正常,但随后退出.我想说的是返回头部,然后调用fact(tail(xs))我该怎么做?

bdo*_*lan 15

您指定的函数仅返回单个元素.您需要将其更改为:

fact [] = [] -- can't call tail on a list of length 0!
fact (xs)   | length( xs ) `mod` 2  == 1 = head( xs ) : fact(tail(xs))
            | otherwise = fact(tail( xs ))
Run Code Online (Sandbox Code Playgroud)

您可能会发现写出类型签名有助于找出像这样的思想:

fact :: [a] -> [a] -- convert a list of anything to another (shorter) list
Run Code Online (Sandbox Code Playgroud)

但请注意,这非常慢 - 实际上是O(n ^ 2),因为它在每一步都需要很长时间.更多haskelly解决方案将使用模式匹配来一次处理两个元素:

fact :: [a] -> [a]
-- Take the first element of each two-element pair...
fact (x:_:xs) = x:fact xs
-- If we have only one element left, we had an odd-length list.
-- So grab the last element too.
fact [x]      = [x]
-- Return nothing if we have an empty list
fact _        = []
Run Code Online (Sandbox Code Playgroud)


yfe*_*lum 14

Haskell中没有任何陈述.

你不应该滥用Haskell中的括号.相反,你应该习惯自己的语言.所以你的原始代码应该是这样的

fact xs | length xs `mod` 2 == 1 = head xs
        | otherwise              = fact (tail xs)
Run Code Online (Sandbox Code Playgroud)

正如bdonlan所说,你正在寻找的功能是真的

fact []       = []
fact [x]      = [x]
fact (x:_:xs) = x : fact xs
Run Code Online (Sandbox Code Playgroud)

假设我们有这个清单[a, b, c, d].让我们应用该函数并完全评估结果.

fact [a, b, c, d] = a : fact [c, d]
                  = a : c : fact []
                  = a : c : []
                  = [a, c]
Run Code Online (Sandbox Code Playgroud)

请注意,这[a, b, c, d]与完全相同, a : b : c : d : []因为编译器可以互换地解释表示列表的两种方式.

  • 我认为还有另一个原因,我们不使用"长度"解决方案.不仅效率.您指定的任务对无限列表也有意义.使用无限列表不仅仅是一种诡辩,因为Haskell的懒惰本质可以提供方法,使用无限列表可以证明是合理的."长度" - 使用解决方案仅适用于有限列表,而"懒惰"方法适用于无限列表和有限列表.OFF:有时,懒惰的评估可以提供非常强大且不直观("神奇")的方法,例如循环编程,repmin问题. (4认同)