Haskell - 如何创建一个从列表中返回第五个元素的函数

时间:2012-01-14 08:39:47

标签: list function haskell

如何在Haskell中创建一个返回列表中第五个元素的函数。

这样的事情:

fifth [] = []!!4

应该返回:

*Main> fifth [1,2,3,20,30,40]
30

3 个答案:

答案 0 :(得分:11)

只需使用:

fifth :: [a] -> a
fifth l = l !! 4

使用你建议的fifth []是错误的,因为这会将列表与空列表进行模式匹配 - 你只需要将变量名称绑定到完整列表,这样就可以使用!!函数之后。

您甚至可以将功能定义为:

fifth :: [a] -> a
fifth = (!!4)

这里我们使用partial application:您通常认为!!是一个带有两个参数的函数:列表和整数。我们可以为它提供一个参数,并获得一个只接受列表的新函数(fifth)。当我们为(!!4)提供一个列表时,它会返回第五个元素:

Prelude> let fifth = (!!4)
Prelude> fifth [1,2,3,20,30,40]
30

该功能当然是部分功能,因为它对于小列表会失败:

Prelude> (!!4) [1,2,3,20]
*** Exception: Prelude.(!!): index too large

这是可以预料的。如果您愿意,可以让它返回Maybe a而不是a ::

,以确保安全
fifth :: [a] -> Maybe a
fifth (a:b:c:d:e:rest) = Just e
fifth _ = Nothing

这里第一个模式将匹配长度为5或更多的列表,第二个模式匹配第一个模式不匹配的任何内容。你这样使用它:

*Main> fifth [1,2,3,20,30,40]
Just 30
*Main> fifth [1,2,3,20]
Nothing

您现在已经强制始终将fifth的结果与Just aNothing进行模式匹配。这意味着当您对来电fifth someList进行编码时,必须会考虑someList可能太短。这样你就可以确保编译时从这个函数中不会出现任何 runtime 错误。

答案 1 :(得分:8)

我会定义一个安全索引操作符!!!,然后根据fifth定义!!!

(!!!)                  :: [a] -> Int -> Maybe a
xs       !!! n | n < 0 =  Nothing
[]       !!! _         =  Nothing
(x : _)  !!! 0         =  Just x
(_ : xs) !!! n         =  xs !!! (n - 1)

fifth :: [a] -> Maybe a
fifth =  (!!! 4)

答案 2 :(得分:5)

另一个不安全的变体

fifth = head . drop 4

但是,嘿,有时候只知道这个该死的名单会有4个以上的元素。类型系统的功能不足以表达它(使用标准列表)。