gpt4 book ai didi

list - Haskell:使用列表理解将字符串更改为全大写字母字符串

转载 作者:行者123 更新时间:2023-12-01 23:02:44 25 4
gpt4 key购买 nike

我发现与递归相比,列表理解几乎是不可能的。我正在尝试获取诸如“te1234ST”之类的字符串并返回“TEST”。看起来很简单,但有限制。不允许使用任何 Haskell 预定义函数,例如 isAlpha 并且它必须是列表理解。

到目前为止我所拥有的,对于我花了多长时间来说非常糟糕:

    convertAllToUpper :: String -> String
convertAllToUpper xs = [n |n <- xs, check n == True]

-- This may not even be allowed, and I know it's incorrect anyway
check :: n -> Bool
check (n:ns)
| n `elem` ['a'..'z'] = True
| n `elem` ['A'..'Z'] = True
| otherwise = False

我只是想让它工作,我什至还没有开始担心将小写更改为大写。

任何正确方向的观点都将非常感激。

编辑:应该提到从下到上的转换不能使用:if, then, else。简单地列出理解和列出运算符。

最佳答案

您的问题可以分解为两个子问题:

  • 仅选择字母字符('a' 和 'z' 之间的字符,或 'A' 和 'Z' 之间的字符)
  • 将小写字符转换为大写。

  • 前者可以通过过滤器或(在列表理解中)对所选元素的条件来完成。在Unicode(和ASCII)中小写字符在大写字符之后,所以我们可以简单地检查字符是否小于'a'来确定它是否是大写(一旦我们知道它是一个字母),并且所有字母字符都是英文-字母顺序,例如小写字母是介于 'a' 和 'z'(含)之间的字母。

    使用 Data.Char (chr, ord):
    f xs = [ if x < 'a' then x else chr $ ord x + ord 'A' - ord 'a'
    | x <- xs, (x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z') ]

    仅使用 Prelude(但最好使用 Data.Map 编写):
    f xs = [ if x < 'a' then x else maybe x id $ lookup x charMap
    | x <- xs, (x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z') ]
    where charMap = zip ['a' .. 'z'] ['A' .. 'Z']

    正确的方法当然是使用标准库。这可以通过一些基本函数轻松完成:
    -- with Data.Char (toUpper, isAlpha)
    f xs = [ toUpper x | x <- xs, isAlpha x ]

    这在很多方面都非常优越:它可能更快,并且它不依赖于 ASCII 输入——它可以处理任何 Unicode 字符(原则上任何本地化:例如,土耳其语“i”正确地大写为“İ” ,而不是 ASCII 或英语语言环境中的 'I',因为 'I' 是 'ı' 的大写,但我不知道是否有任何 Haskell 实现正确地实现了这一点)。

    请注意,列表推导式是递归的一个子集:如果您可以设法编写以下形式的递归函数:
    f []       = []
    f (x : xs) = if p x then g x : f xs else f xs

    它可以机械地转换为以下形式的列表理解式:
    f xs = [ g x | x <- xs, p x ]

    虽然您也可以拥有多变量列表表达式,但递归表达会稍微复杂一些。因此,如果您了解递归,那么列表推导式对您来说应该是微不足道的。

    关于list - Haskell:使用列表理解将字符串更改为全大写字母字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14915611/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com