P01 - 取列表最后一个元素

2026-09-07 00:00    #Haskell   #99题   #列表  

P01 - 取列表最后一个元素

Last element of a list

官方模块: Problems.P01 核心函数: myLast


P02 取列表倒数第二个元素 →



P02 取列表倒数第二个元素 →


题目描述

找出列表的最后一个元素。如果列表为空,返回 Nothing

这是列表类问题中最基础的一道,目的是熟悉 Haskell 的递归模式匹配和 Maybe 类型。

函数签名

1myLast :: [a] -> Maybe a

输入一个列表,返回 Just 最后一个元素,空列表返回 Nothing

思路

Haskell 处理列表的经典手法是递归 + 模式匹配。列表有两种 case:

实现

方法一:标准递归

这是最直接、最符合 Haskell 风格的写法:

1myLast :: [a] -> Maybe a
2myLast []      = Nothing
3myLast [x]     = Just x
4myLast (_:xs)  = myLast xs

模式匹配天然处理了三种情况:

这种写法的好处是可读性极强,几乎就是题目描述的直接翻译。

方法二:使用 last + Maybe 包装

Haskell 标准库已经有 Prelude.last 函数,但它对空列表抛异常。我们可以封装一层:

1import Prelude hiding (last)
2
3myLast :: [a] -> Maybe a
4myLast [] = Nothing
5myLast xs = Just (Prelude.last xs)

或者更紧凑地用 maybelistToMaybe(来自 Data.Maybe):

1import Data.Maybe (listToMaybe)
2
3myLast :: [a] -> Maybe a
4myLast = listToMaybe . reverse

reverse 把列表反转,listToMaybe 取反转后列表的第一个元素(即原列表的最后一个),对空列表自动返回 Nothing

方法三:使用 foldl'

函数式风格还可以用 fold 实现:

1myLast :: [a] -> Maybe a
2myLast [] = Nothing
3myLast xs = Just . foldl' (\_ x -> x) (head xs) $ xs

但这种方法不如模式匹配直观,仅供理解 fold 的参考。

测试

用官方给出的例子验证:

 1-- 基础测试
 2>>> myLast [1,2,3,4]
 3Just 4
 4
 5>>> myLast ['x','y','z']
 6Just 'z'
 7
 8>>> myLast []
 9Nothing
10
11-- 单元素列表
12>>> myLast [42]
13Just 42
14
15-- 嵌套列表(注意类型是 List of Lists)
16>>> myLast [[1,2],[3,4]]
17Just [3,4]

要点总结

参考


P02 取列表倒数第二个元素 →