从字符串到列表的单词

穆苏哈尼夫

我正在尝试编写一个 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 的新手,所以我不了解它的语法,所以在此先感谢您的帮助。

尼法特尔

这里有很多错误,你应该花更多的时间阅读一些教程(学习你的 HaskellReal World Haskell)。不过你已经很接近了,所以我会试着在这里做一个分解。

do很特别 - 它不会将 Haskell 切换到“命令模式”,它可以让您在使用 Monads 时编写更清晰的代码 - 如果您还不知道 Monads 是什么,请远离do关键字 likereturn也与命令式语言中的行为不同。尝试以全新的心态接近 Haskell。

同样在 Haskell 中,缩进很重要 - 请参阅此链接以获得很好的解释。本质上,您希望同一“块”中的所有行都具有相同的缩进。


好的,让我们去掉doandreturn关键字,并对齐缩进。我们还将为函数命名参数str- 在您的原始代码中,您错过了这一点。

toWordList :: String -> [String]
toWordList str =
    [toLower x | x <- str]
    let var = removePunctuation(x)
    words var

的语法letlet __ = __ 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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章