获取列表中的最后一个元素而不使用模式匹配

Rau*_*des 0 haskell

我一直得到"错误:输入解析错误'|' "有人可以告诉我为什么吗?我已经重写了它,以确保所有正确的空格都是我的代码:

 mylast :: (Eq a) => [a] -> [a]  
 mylast [] = []  
 mylast (x:xs)  
   | xs == [] : x  
   | otherwise = mylast xs   
Run Code Online (Sandbox Code Playgroud)

Dan*_*ner 7

修复这个确切错误所需的最小变化只是为了解决可能是一个错字:你写的xs == [] : x,也许意味着xs == [] = x.所以:

mylast :: (Eq a) => [a] -> [a]
mylast [] = []
mylast (x:xs)
  | xs == [] = x
  | otherwise = mylast xs
Run Code Online (Sandbox Code Playgroud)

这将给你一个类型错误,因为x是一个列表元素,你说mylast返回一个列表.您可以通过将其[x]设为单个列表来解决此问题,如:

mylast :: (Eq a) => [a] -> [a]
mylast [] = []
mylast (x:xs)
  | xs == [] = [x]
  | otherwise = mylast xs
Run Code Online (Sandbox Code Playgroud)

从那里,我有一些风格的评论.

  1. 我喜欢你的想法是返回一个列表,这样如果输入为空,你就不需要抛出错误.但是因为我们肯定会返回最多一个元素,所以您可以考虑使用Maybe此角色而不是[]; 它提供了至多一个元素的类型级保证.
  2. 这种Eq a约束是不幸的:它是因为你编写xs == []而产生的,实际上并不需要调用(==)任何元素,但仍需要用户提供(==)on元素的实现.检查列表是否为空的标准方法是调用null或直接使用模式匹配,这两者都不需要Eq.

结合这两个想法,我们得到:

mylast :: [a] -> Maybe a
mylast [] = Nothing
mylast [x] = Just x -- convenient syntax sugar for mylast (x:[]) = Just x
mylast (x:xs) = mylast xs
Run Code Online (Sandbox Code Playgroud)

这对我来说非常惯用.