我在使用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,但我不知道如何操作。对不起,如果这是一个愚蠢的问题,但我发现的任何内容都无法解决我的困惑。
答案 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)