gpt4 book ai didi

haskell - 选择列表的倒数第二个元素

转载 作者:行者123 更新时间:2023-12-04 12:47:33 24 4
gpt4 key购买 nike

一段时间后,我决定重新学习一些函数式编程。这次我决定选择 Haskell,因为它的特性和 .. 语法。

目前我正在做一些练习,但我被卡住了。我想编写一个从列表中选择倒数第二个元素的函数,即给定 [1,2,3,4] 它将是 3。

这是我的功能。

lastButOne xs 
| null xs = xs
| length xs == 1 = xs
| length xs == 2 = lastButOne head xs
| otherwise = lastButOne tail xs

不幸的是,它会产生一些错误。
Couldn't match expected type `[a]' with actual type `[a1] -> [a1]'
Relevant bindings include
xs :: [a] (bound at lastButOne.hs:1:12)
lastButOne :: [a] -> [a] (bound at lastButOne.hs:1:1)
Probable cause: `tail' is applied to too few arguments
In the first argument of `lastButOne', namely `tail'
In the expression: lastButOne tail xs

我尝试过一些部分性,比如 (head xs) 和 (tail xs),但它没有帮助。
   Occurs check: cannot construct the infinite type: a ~ [a]
Expected type: [[a]]
Actual type: [a]
Relevant bindings include
xs :: [a] (bound at lastButOne.hs:1:12)
lastButOne :: [a] -> [a] (bound at lastButOne.hs:1:1)
In the first argument of `head', namely `xs'
In the first argument of `lastButOne', namely `(head xs)'

跟进 :
或者我应该写后续的。好吧,我最初的想法是编写一个函数,如果列表长度为 1,则该函数会生成头元素。因此,鉴于李的解释,很容易得出以下结论:
lastPattern :: [a] -> Maybe a
lastPattern [] = Nothing
lastPattern [x] = Just x
lastPattern [x,_] = Just x
lastPattern (_:xs) = lastPattern xs

这是第一个问题。条件 [x] 和 [x,_] 的模式是什么?

接下来我想做的是用相反的方式编写相同的函数(正如 Paul Johnson 所指出的)。我很快想出了 head (tail (reverse [1,2,3,4]))这似乎在 REPL 中运行良好。但是当我开始一些编码时,我最终得到了
 lastRev :: [a] -> a
lastRev xs
| null xs = error "empty list"
| length xs == 1 = error "too short"
| otherwise = head (tail (reverse xs))

因为 head 函数是 head :: [a] -> a .上面的功能对我来说有点乱,可以这么说。有什么办法可以让它成为 :: [a] -> Maybe a ?那是第二个问题。

最后但并非最不重要的 - 第三个问题。哪个功能在性能方面更好?如何在 Haskell 中测量它?

最佳答案

(head xs)返回 a而你正试图将它传递给 lastButOne这需要一个 [a]争论。您可以直接返回 head xs在这种情况下直接。前两种情况也有问题,因为它们返回一个列表,而需要一个元素。由于在这种情况下没有这样的元素,您可能会返回错误:

lastButOne :: [a] -> a
lastButOne xs
| null xs = error "empty list"
| length xs == 1 = error "list too short"
| length xs == 2 = head xs
| otherwise = lastButOne (tail xs)

更实用的解决方案是在函数类型中编码偏爱并返回 Maybe a所以你可以返回 Nothing如果输入列表太短:
lastButOne :: [a] -> Maybe a
lastButOne xs
| null xs = Nothing
| length xs == 1 = Nothing
| length xs == 2 = Just (head xs)
| otherwise = lastButOne (tail xs)

最后,更好的解决方案是使用模式匹配而不是保护长度:
lastButOne :: [a] -> Maybe a
lastButOne [] = Nothing
lastButOne [_] = Nothing
lastButOne [x,_] = Just x
lastButOne (_:xs) = lastButOne xs

关于haskell - 选择列表的倒数第二个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31484511/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com