haskell - Haskell 中应该避免 do 表示法吗?

标签 haskell functional-programming io monads do-notation

大多数 Haskell 教程都会教授 IO 的 do-notation 的使用。

我也从 do 表示法开始,但这使我的代码看起来更像是命令式语言,而不是 FP 语言。

本周我看到了一个使用 IO 的教程 <$>

stringAnalyzer <$> readFile "testfile.txt"

而不是使用 do

main = do
    strFile <- readFile "testfile.txt"
    let analysisResult = stringAnalyzer strFile
    return analysisResult

日志分析工具就完成了,没有do .

所以我的问题是“在任何情况下我们都应该避免使用 do 符号吗?”。

我知道也许do在某些情况下会使代码变得更好。

另外,为什么大多数教程都用 do 来教授 IO ?

我认为<$><*>使代码比 IO 更 FP。

最佳答案

do Haskell 中的表示法以一种非常简单的方式脱糖。

do
  x <- foo
  e1 
  e2
  ...

变成了

 foo >>= \x ->
 do
   e1
   e2

do
  x
  e1
  e2
  ...

进入

x >>
do 
  e1
  e2
  ....

这意味着您确实可以使用 >>= 编写任何单子(monad)计算和return 。我们不这样做的唯一原因是因为它的语法更痛苦。 Monad 对于模仿命令式代码很有用,do符号使它看起来像这样。

C 风格的语法使初学者更容易理解它。你是对的,它看起来并不实用,但要求某人在使用 IO 之前正确理解 monad 是一个相当大的威慑。

我们使用 >>= 的原因和return另一方面是因为它对于 1 - 2 个衬垫来说更加紧凑。然而,对于太大的东西来说,它确实会变得更加难以阅读。因此,为了直接回答您的问题,不,请不要在适当的时候避免使用 do 符号。

最后你看到的两个运算符,<$><*> ,实际上分别是 fmap 和 applicative,而不是 monadic。它们实际上不能用来表示 do 表示法的很多功能。当然,它们更紧凑,但它们不允许您轻松命名中间值。就我个人而言,我大约 80% 的时间都在使用它们,主要是因为我倾向于编写非常小的可组合函数,而这些应用程序非常适合。

关于haskell - Haskell 中应该避免 do 表示法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16726659/

相关文章:

C++ 写入选项

有效 JSON 的 Python json.load(file) 错误

列表 - 组合对

http - 使用 GZIP 压缩的 HTTP 请求内容被截断(仅在浏览器中)

functional-programming - SML 中的 List.nth 内部究竟发生了什么?

.net - F# - 不理解函数组合(将获取文件函数转换为获取重复文件函数)

java.util.zip - ZipInputStream 对比压缩文件

haskell - 使用foldl反转列表?

haskell - 类型良好的函数的 eta 减少如何导致类型错误?

algorithm - 在 Haskell 中解决代码厨师(CHEF 和​​ Way)上的 CHRL4