我不断收到“错误:分析输入内容'|'的错误”,有人可以告诉我原因吗?我已经重写了它以确保所有空格正确 这是我的代码:
mylast :: (Eq a) => [a] -> [a]
mylast [] = []
mylast (x:xs)
| xs == [] : x
| otherwise = mylast xs
答案 0 :(得分:7)
解决该确切错误所需的最小更改只是为了解决可能是错字的问题:您写了xs == [] : x
,可能是xs == [] = x
的意思。所以:
mylast :: (Eq a) => [a] -> [a]
mylast [] = []
mylast (x:xs)
| xs == [] = x
| otherwise = mylast xs
这将给您键入错误,因为x
是一个列表元素,并且您说mylast
返回一个列表。您可以通过使其成为单例列表[x]
来解决此问题,如下所示:
mylast :: (Eq a) => [a] -> [a]
mylast [] = []
mylast (x:xs)
| xs == [] = [x]
| otherwise = mylast xs
从那里,我有一些风格上的评论。
Maybe
代替该角色[]
;它提供了最多一个元素的类型级别保证。Eq a
约束是由于您写了xs == []
而产生的,实际上并不需要在任何元素上调用(==)
,但是仍然需要用户提供实现(==)
在元素上。检查列表是否为空的标准方法是调用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
这对我来说很惯用。
答案 1 :(得分:1)
如果您真的想避免编写任何模式,则最简单的方法可能是foldl'
:
mylast :: [a] -> Maybe a
mylast = foldl' (\_ x -> Just x) Nothing
如果愿意,可以深入了解列表foldr
上的原始变形:
mylast :: [a] -> Maybe a
mylast xs = foldr (\x r _ -> r (Just x)) id xs Nothing
但这有点难以理解。
foldl'
和foldr
最终是使用模式匹配实现的,因为这是检查Haskell中列表的基本底层方法。因此,没有任何方法可以真正完全避免它。