考虑以下有效的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
?
答案 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
有效,但它并没有真正传达main
和a
b
x
块中的内容,所以它是一个再稍微缩进它们会更好一点:
do