1

以下是我复制的示例:

charName :: Char -> String
charName 'a' = "Albert"
charName 'b' = "Broseph"
charName 'c' = "Cecil"
charName x = "尚未定义"

我可以将上述代码进一步修改为如下所示(不会编译):

charName :: Char -> String
charName 'a' or 'A' = "Albert"
charName 'b' or 'B' = "Broseph"
charName 'c' or 'C' = "Cecil"
charName x or X= "Not尚未定义”

如果给定 charName 'a' 或 charName 'A',则为了获得“Albert”。

请指导如何以最短的方式编写上述代码。

4

4 回答 4

5

另一种选择是:

charName :: Char -> String
charName ch 
 | ch `elem` "aA" = "Albert"
 | ch `elem` "bB" = "Broseph"
 | ch `elem` "cC" = "Cecil"
 | otherwise = "Not defined yet" 
于 2012-06-29T07:05:48.577 回答
4

与 Mihai 的答案类似,您可以使用 case 语句,它允许您进行模式匹配,而无需定义额外的函数:

import Data.Char (toLower)

charName :: Char -> String
charName c = case toLower c of
              'a' -> "Albert"
              'b' -> "Broseph"
              _   -> "Not defined yet"
于 2012-06-29T08:17:02.280 回答
3

您可以使用toLowerfromData.Char和函数组合。一种解决方案是

charName :: Char -> String
charName = charName' . toLower
    where
        charName' 'a' = "Albert"
        charName' 'b' = "Broseph"
        charName' 'c' = "Cecil"
        charName' _   = "Not defined yet"

另外,对于最后一种情况,如果您想返回错误,为什么不使用undefinedor error error_msg

于 2012-06-29T06:04:59.967 回答
2
import Data.List (find)

charName :: Char -> String
charName c = maybe "Not defined yet" snd $ find (elem c . fst)
  [ ( "aA", "Arthur" )
  , ( "bB", "Broseph" )
  , ( "cC", "Cecil" )
  ]

使用的解释:

  • fstsnd:分别提取元组的第一个或第二个元素
  • Data.List.find: 找到满足给定谓词的列表元素
  • maybe: 处理Maybe价值观。find产生一个Maybe结果,所以你必须处理失败的情况。在这种情况下,我选择(和你一样)字符串“尚未定义”
  • elem:确定给定列表中是否包含某些内容(用法类似于 Landei 的答案)。回想一下,String它表示为 的列表Char
  • 函数组合:.表达式中的(elem c . fst)组合了两个函数。也就是说,它获取其输入元组,访问第一个元素(即 a String),然后确定是否c是该字符串中的一个字符。函数组合从右到左读取。
  • $: 美元符号是函数应用。它主要用于避免括号。有各种 StackOverflow 答案详细说明了.和的用法$
于 2012-06-29T09:40:09.483 回答