在Haskell中使用isUpper,isLower和isDigit

时间:2017-09-14 06:18:27

标签: haskell

我在使用isUpper,isLower和isDigit方面遇到了麻烦。具体来说,我试图获取一个字符串,并返回包含三个Bool值的字符串中每个字符的元组列表,如果该字符是大写字母,小写字母或数字。所以字符串" Ab2"将返回列表[(True,False,False),(False,True,False),(False,False,True)]。这就是我所拥有的:

import Data.Char
uppercaseList :: [a] -> [(Bool, Bool, Bool)]
uppercaseList xs = [(isUpper, isLower, isDigit)]

我想我需要将字符串的字符传递给isUpper,isLower和isDigit,但我不知道如何操作。对不起,如果这是一个愚蠢的问题,但我发现的任何内容都无法解决我的困惑。

2 个答案:

答案 0 :(得分:7)

您需要检查列表中的每个元素(xs)。通常这种任务是使用map

完成的
import Data.Char
uppercaseList :: String -> [(Bool, Bool, Bool)]
uppercaseList xs = map (\x -> (isUpper x, isLower x, isDigit x)) xs

或列表理解

uppercaseList xs = [ (isUpper x, isLower x, isDigit x) | x <- xs ]

或从头开始写

uppercaseList [] = []
uppercaseList (x:xs) = (isUpper x, isLower x, isDigit x) : uppercaseList xs

答案 1 :(得分:2)

您的方法存在问题:

uppercaseList xs = [(isUpper, isLower, isDigit)]

根本不考虑列表xs :它在正文中没有提到。这意味着xs对输出没有影响。

你所做的是使用一个元素构建一个列表作为输出:一个包含三个函数的元组(是的,这些是函数,而不是Bool或多个)。

为了检查角色,你需要调用列表元素上的函数。

使用map :: (a -> b) -> [a] -> [b]调用列表上的函数。 Map将第一个参数作为函数f,将第二个参数作为元素列表(例如[x1, x2, x3, x4])。它在函数的所有元素上应用函数f,并生成列表[f x1, f x2, f x3, f x4])。这是以懒惰的方式完成的。

这里我们需要一个函数f :: Char -> (Bool, Bool, Bool)。根据规范,该功能如下:

import Data.Char(isUpper, isLower, isDigit)

f :: Char -> (Bool, Bool, Bool)
f x = (isUpper x, isLower x, isDigit x)

然后我们可以写:

uppercaseList :: [Char] -> [(Bool, Bool, Bool)]
uppercaseList = map f

因为在文件的顶层看到一个函数f(我们当然可以给它一个更具语义的名称)是很奇怪的。我们可以决定对其进行范围化(或者使用 lambda表达式):

uppercaseList :: [Char] -> [(Bool, Bool, Bool)]
uppercaseList = map f
    where f x = (isUpper x, isLower x, isDigit x)