Monadic里面的符号让,有可能吗?

时间:2015-11-27 18:30:37

标签: haskell let do-notation

考虑以下有效的Haskell代码

module Main where

main :: IO ()
main = do
  let x = f
  print x

f :: Maybe (Int, Int)
f =
  Just 3 >>= (\a ->
    Just 5 >>= (\b ->
      return (a, b)))

其中函数f可以用这样的do-notation等效地重写

f :: Maybe (Int, Int)
f = do
  a <- Just 3
  b <- Just 5
  return (a, b)

让我感到恼火的是,当我将f的内容放入内联时,符号表示无效。以下代码甚至不解析:

main :: IO ()
main = do
  let x = do
    a <- Just 3
    b <- Just 5
    return (a, b)
  print x

我在let里面是否正确我被迫诉诸(>>=)

虽然我正在使用它,但以下代码无法解析:

module Main where

main :: IO ()
main = do
  let x =
    Just 3 >>= (\a ->
      Just 5 >>= (\b ->
        return (a, b)))
  print x

除了let不必要的有限权力之外,我没有看到明显的原因。是否有一种优雅的方式在bind内使用let

1 个答案:

答案 0 :(得分:8)

  

我在null里面是否正确我被迫诉诸let

没有

(>>=)

Haskell的layout规则规定main :: IO () main = do let x = do a <- Just 3 b <- Just 5 return (a, b) print x 中绑定e的主体至少与p = e的开头(或第一个绑定,如果你一次使用多个)。由于p中的let遵循(几乎)与do相同的规则,因此您可以使用以下函数对此进行验证:

let … in

这不起作用,因为f :: Int f = let x = 3 + 5 in x 3 + 5的缩进级别不同或更高。然而,

x

的工作原理。此外,虽然上面的f :: Int f = let x = 3 + 5 in x 有效,但它并没有真正传达maina b x块中的内容,所以它是一个再稍微缩进它们会更好一点:

do