我正在尝试编写一个 Haskell 函数,它会读取一个字符串并返回一个列表,其中包含保存在其中的字符串中的单词。
这是我如何做到的:
toWordList :: String -> [String]
toWordList = do
[ toLower x | x <- str ]
let var = removePunctuation(x)
return (words var)
但我收到此错误:
Test1.hs:13:17: error: parse error on input 'let'
|
13 | let var = removePunctuation(x)
| ^^^
我是 Haskell 的新手,所以我不了解它的语法,所以在此先感谢您的帮助。
这里有很多错误,你应该花更多的时间阅读一些教程(学习你的 Haskell,Real World Haskell)。不过你已经很接近了,所以我会试着在这里做一个分解。
do
很特别 - 它不会将 Haskell 切换到“命令模式”,它可以让您在使用 Monads 时编写更清晰的代码 - 如果您还不知道 Monads 是什么,请远离do
!关键字 likereturn
也与命令式语言中的行为不同。尝试以全新的心态接近 Haskell。
同样在 Haskell 中,缩进很重要 - 请参阅此链接以获得很好的解释。本质上,您希望同一“块”中的所有行都具有相同的缩进。
好的,让我们去掉do
andreturn
关键字,并对齐缩进。我们还将为函数命名参数str
- 在您的原始代码中,您错过了这一点。
toWordList :: String -> [String]
toWordList str =
[toLower x | x <- str]
let var = removePunctuation(x)
words var
的语法let
是let __ = __ in __
。使用时有不同的表示法do
,但暂时忘记这一点。我们也不命名列表推导式的结果,所以让我们这样做:
toWordList str =
let lowered = [toLower x | x <- str] in
let var = removePunctuation lowered in
words var
这有效!我们只需要一些语法正确,避免了一元语法糖do
/ return
。
不过,让它变得更好是可能的(并且很容易)。那些let
块有点丑,我们可以把它们去掉。我们也可以用 替换列表推导式map toLower
,这样更优雅一点,相当于您的推导式:
toWordList str = words (removePunctuation (map toLower str))
很好,现在只剩下一行了!但所有这些括号也有点碍眼的,怎么样,我们使用的$
功能?
toWordList str = words $ removePunctuation $ map toLower str
看起来不错。我们还可以进行另一项改进,即将其转换为无点样式,其中我们没有明确命名我们的参数 - 而是将此函数表示为其他函数的组合。
toWordList = words . removePunctuation . (map toLower)
我们完成了!希望前两个代码片段更清楚地说明 Haskell 语法的工作原理,最后几个可能会向您展示一些很好的示例,说明如何使相当冗长的代码更加清晰。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句