Haskell - 检查列表的最后一项

时间:2017-09-20 05:01:41

标签: list haskell uppercase

我需要检查列表的最后一个元素是否为大写 例如"abc" - False"abC" - True

这就是我的尝试

checkLast :: [a] -> Bool
checkLast [] = False
checkLast [x] = if isUpper x then True else False
checkLast (x:xs) = if isUpper last then True else False

5 个答案:

答案 0 :(得分:4)

递归思考。 checkLast (x:xs)只是检查checkLast xs

checkLast :: [Char] -> Bool
checkLast [] = False
checkLast [x] = isUpper x
checkLast (x:xs) = checkLast xs

请注意,由于您使用isUpper来检查字符串,因此更有意义的是类型应为[Char],而不是[a]

答案 1 :(得分:2)

您可以像其他答案演示一样使用递归。但是你也可以使用内置函数来构造这样的函数。

这里的两个相关函数是null :: [a] -> Bool,它检查列表是否为空,以及last :: [a] -> a获取最后一个元素。

现在我们可以构建一个函数:

import Data.Char(isUpper)

checkLast :: [Char] -> Bool
checkLast l = not (null l) && isUpper (last l)

因此,如果列表checkLast不为空(True),我们在此声明lnot (null l);最后一个元素是大写字符isUpper (last l)

这可能比递归函数快一点,因为我们只测试[]一次(在null中)。 last仅检查两种情况:[x](x:xs),因此我们会保存[]次检查。

当然这些函数与递归一起工作,但有时候查找辅助函数很有用,这样函数几乎可以自我解释:这里的函数说:“列表l是{{1如果它不为空,则最后一个元素是大写“。

答案 2 :(得分:1)

带注释的固定版本:

import Data.Char (isUpper)

checkLast :: [Char] -> Bool      -- it cannot be [a]: use of isUpper already limits possible type to [Char]
checkLast [] = False
checkLast [x] = isUpper x        -- the if .. can be shorter
checkLast (x:xs) = checkLast xs  -- drop first char and look at rest of string

答案 3 :(得分:1)

如果您希望这样做,避免显式递归的最简单方法可能是使用折叠:

lastMay :: [a] -> Maybe a
lastMay = foldl' (\_ x -> Just x) Nothing

checkLast = maybe True isUpper . lastMay

答案 4 :(得分:-2)

您也可以在没有任何递归的情况下执行以下操作

import Data.Char

checkLast :: String -> Bool
checkLast = (&&) <$> not . null <*> isUpper . head . reverse

应用运算符<*>是一个理想的工具,可以将公共参数(此处为输入字符串)提供给两个不同的函数,如not . nullisUpper . head . reverse,然后进行操作{ {1}}他们的结果。

根据@ dfeuer的评论,我只想附上以下解决方案以获得更好的性能。您不需要导入除(&&)

之外的任何其他包
Data.Char