检查字符串是否包含非字母字符

时间:2018-12-08 22:36:02

标签: string haskell character

我有以下测试案例:

abc :: ABC 
abc = ['A'..'Z'] ++ ['a'..'z']

startState :: ABC -> String -> Maybe (String, [Char], [Char])
startState abc "Save Our Souls"  == Just ("SAVE OUR SOULS", "", "")
startState abc "Save Our Souls!" == Nothing

简而言之,如果字符串包含的字符不是abc的一部分(在示例中,第三行包含!),则该函数应不输出任何内容,否则应像示例中那样打印字符串。 / p>

这是我的代码:

startState :: ABC -> String -> Maybe (String, [Char], [Char])
startState abc "" = Just ("","","")
startState abc word = Just (word,"","")
startState abc word
 | word `elem` abc   = Just (word,"","")
 | otherwise         = Nothing

我得到错误:Couldn't match type Char' with [Char]'

3 个答案:

答案 0 :(得分:2)

您收到错误Couldn't match type ‘Char’ with ‘[Char]’,因为您试图将elem应用于类型为word的{​​{1}}和类型为[Char]的{​​{1}}也输入abc,而[Char]的类型签名是:

elem

因此,在您的情况下,应将其应用于elem :: (Foldable t, Eq a) => a -> t a -> Bool Char

[Char]

如果要检查elem :: Char -> [Char] -> Bool 的所有字符是否都是word的元素,则可以使用函数Data.List.all执行以下操作:

abc

这会将功能startState abc word | all (flip elem abc) word = Just (word,"","") | otherwise = Nothing 应用于flip elem abc中的每个字符,并且当所有字符都是word的元素时返回True

您还应该删除这两行:

abc

因为您不需要第一个,而第二个与第三个模式相同,所以它将使第三个模式匹配变得多余。并且还需要在startState abc "" = Just ("","","") startState abc word = Just (word,"","") 的定义中添加++ [' '],以使测试用例通过。

答案 1 :(得分:1)

假设ABCString的同义词,那么错误就出在这里:

 | word `elem` abc   = Just (word,"","")

elem的类型签名为a -> [a] -> Bool。由于wordabc基本上都具有String的类型,因此这不适合elem的类型签名。

由于您要测试word的每个元素,因此这是一种解决方案:

 | all (`elem` abc) word = Just (word,"","")

all来自前奏。

编辑:另外请注意,abc是不明确的。它定义为类型为ABC的常量,但它也是startState的参数。删除该参数:

abc :: ABC
abc = ['A'..'Z'] ++ ['a'..'z']

startState :: String -> Maybe (String, [Char], [Char])
startState "" = Just ("","","")
startState word
 | word `elem` abc   = Just (word,"","")
 | otherwise         = Nothing

答案 2 :(得分:0)

另一种替代方法是将其全部打包到一个函数中,并使用软件包ord中的函数Data.Char。该函数将字符转换为等效的十进制数。通过检查ascii表,您可以清楚地看到所需字符的边界。下面的代码:

conv :: String -> String
conv (x:xs) 
    | ord >= 65 && ord x <= 91  = [x] ++ conv xs
    | ord >= 97 && ord x <= 122 = [x] ++ conv xs
    | otherwise                 = "" ++ conv xs