【问题标题】:Equivalent of Haskell do-notation or F# Computation Expressions in Scala?等效于 Scala 中的 Haskell do-notation 或 F# 计算表达式?
【发布时间】:2011-11-20 18:02:23
【问题描述】:

F# 计算表达式允许将一元语法的复杂性隐藏在一层厚厚的语法糖后面。 Scala 中是否有类似的功能?

我认为这是为了理解......

例子:

val f = for {
  a <- Future(10 / 2) // 10 / 2 = 5
  b <- Future(a + 1)  //  5 + 1 = 6
  c <- Future(a - 1)  //  5 - 1 = 4
 } yield b * c         //  6 * 4 = 24

 val result = f.get

但感觉不太对劲。有更好的语法吗?

例如在haskell中你会拥有

main = do fromHandle

这与 scala 不同,它看起来不像 foreach 循环。 Scala 语法似乎与列表理解有很强的耦合,这是一个独特的概念。这使我无法编写看起来并不奇怪的内部 DSL (monad)。

【问题讨论】:

  • for 理解是完全正确的。他们在幕后对mapflatMap 脱糖,这正是Haskell do 表示法的工作原理(除了这些方法在Haskell 中称为fmap&gt;&gt;=)。
  • @Dan Burton - 这个问题已经被问过并回答了好几次......我会推荐你​​这个很好的答案:stackoverflow.com/questions/1052476/…
  • 更正我的第一条评论...fmap 实际上并没有在 Haskell 中对 do-notation 进行脱糖,因为没有必要的 yield 声明(而且我们也可以'不确定所有Monads 都是Functors,即使它们应该是)...而不是关键字yield,您只需使用return 函数,当作为@987654336 中的最后一个语句调用时@block,相当于fmap
  • 感觉不对的符号是怎么回事?
  • 当然,我们可以一直争论下去,但这不会改变大多数人for 与循环相关的事实,这是有充分理由的。是的,有可能“克服它”,但这并不能真正改变重点。

标签: scala haskell f# monads do-notation


【解决方案1】:

缺少的部分可能是=的使用是scala的for-comprehensions:

val f = for {
  a <- Future(10 / 2) // 10 / 2 = 5
  b <- Future(a + 1)  //  5 + 1 = 6
  c <- Future(a - 1)  //  5 - 1 = 4
  d = b * c           //  6 * 4 = 24
} yield d


val result = f.get

&lt;-= 巧妙地混合在一起,您应该拥有所需的所有灵活性。

【讨论】:

  • 有时我希望 Haskell 的 do 语法能够从 = 的使用中推断出 let
【解决方案2】:

在 scala 中似乎没有这样的语法可用,我们需要使用编译器插件架构自己实现它。

【讨论】:

  • 我想过使用宏——你考虑过吗?
猜你喜欢
  • 2012-05-13
  • 2018-09-15
  • 2014-03-26
  • 2018-09-05
  • 2013-05-19
  • 2011-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多