我有这个函数,必须检查字符串中的字符是字母,数字还是标点符号,返回True时的情况,否则为False。但如果我测试它,它就不起作用。
punct :: Char -> Bool
punct c | c `elem` ['.', ',', '?', '!', ':', ';', '(', ')'] = True
| c isDigit = True
| c isAlpha = True
| otherwise = False
此功能在上述其中一个之后添加一个空格。
format :: String -> String
format s = intercalate "" [if (punct c) then (c:" ") else [c] | c <- s]
之后,我需要删除上面的内容,在punct中检查。 实际上我认为我可以用空格直接替换那些来自punct的那些 我尝试过这样的事情:
format :: String -> String
format s = map (\c -> if punct c then (c:" ") else [c] )
但它没有用,有什么建议吗?我想我可以使用地图和过滤器?我错了吗?
答案 0 :(得分:2)
不工作的原因是因为map
Char
位于String
上([Char]
s)map
。因此,[String]
的输出将为punct
。不过,如果你想删除上面的那些,你在地图中的功能就不会让你的角色消失。
此外,您isDigit
功能错误。 isDigit c
等是函数。因此,您可以使用c isDigit
,而不是punct :: Char -> Bool
punct c | c `elem` ['.', ',', '?', '!', ':', ';', '(', ')'] = True
| isDigit c = True
| isAlpha c = True
| otherwise = False
:
punct :: Char -> Bool
punct c = isDigit c || isDigit c || c `elem` ['.', ',', '?', '!', ':', ';', '(', ')']
尽管如此,您可以轻松地将此语句更紧凑并将其转换为:
filter
这里有两个选项:(1)你要做一个后期处理,你可以过滤掉所有的标点符号;或者(2)如果你删除标点符号,你实际上是做替换而不是插入空格。
(1)后期处理:
后处理只是post_format :: String -> String
post_format = filter (not . punct)
:
format
如果您仍想使用“原始”helper
功能,最好使用后期处理。
(1)替换:
在这种情况下,您可以使用helper :: Char -> Char
helper x | punct x = ' '
| otherwise = x
函数:
format
然后format :: String -> String
format = map helper
崩溃到:
grid.arrange
答案 1 :(得分:1)
好吧,这段代码不会编译。让我们来解决为什么它不能一次编译一个问题:
首先,在punct
函数中,此编译错误发生两次:
Foo.hs:7:11: error:
• Couldn't match expected type ‘(Char -> Bool) -> Bool’
with actual type ‘Char’
• The function ‘c’ is applied to one argument,
but its type ‘Char’ has none
In the expression: c isDigit
In a stmt of a pattern guard for
an equation for ‘punct’:
c isDigit
编译器在这里试图告诉你的是你写了“call c
作为一个函数,传递参数isDigit
”,显然你的意思是反过来。所以首先我们交换那些:
punct :: Char -> Bool
punct c | c `elem` ['.', ',', '?', '!', ':', ';', '(', ')'] = True
| isDigit c = True
| isAlpha c = True
| otherwise = False
修复后,您的第一个format
函数实际编译:
format1 :: String -> String
format1 s = intercalate "" [if (punct c) then (c:" ") else [c] | c <- s]
它似乎也像宣传的那样工作:
*Foo> format1 "a.b_c"
"a . b _c "
好的,现在第二个format
函数呢?好吧,起初它不会编译:
Foo.hs:18:12: error:
• Couldn't match type ‘[Char] -> [[Char]]’ with ‘[Char]’
Expected type: String
Actual type: [Char] -> [[Char]]
• Probable cause: ‘map’ is applied to too few arguments
In the expression: map (\ c -> if punct c then (c : " ") else [c])
In an equation for ‘format’:
format s = map (\ c -> if punct c then (c : " ") else [c])
编译器在这里告诉你(带有“可能的原因”消息),你忘了在右侧使用s
,并且应该已经写了:
format s = map (\c -> if punct c then (c:" ") else [c] ) s
但是无法编译的事件:(但现在错误信息不同)
Foo.hs:18:12: error:
• Couldn't match type ‘[Char]’ with ‘Char’
Expected type: String
Actual type: [[Char]]
• In the expression:
map (\ c -> if punct c then (c : " ") else [c]) s
In an equation for ‘format’:
format s = map (\ c -> if punct c then (c : " ") else [c]) s
这就是说你的结果应该是String
(即Char
或[Char]
的列表),而是String
的列表(即[[Char]]
)
这是因为您将每个字符转换为字符串,而不是字符。解决此问题的一种方法是将每个字符转换为字符:
format s = map (\c -> if punct c then ' ' else c ) s
另一种方法是像以前一样应用intercalate ""
(或concat
)将字符串列表加入到单个字符串中:
format s = intercalate "" $ map (\c -> if punct c then " " else [c] ) s