Haskell Monadic 形式

发布于 2024-11-18 15:42:48 字数 401 浏览 4 评论 0原文

一个简单的问题: 给定定义,(来自 Haskell SOE)

   do x — el; el\ ...; en 
    => el »= \x — do e2\ ...; en 

并且:

do let decllist; el\...; en 
=> let decllist in do e2\ ...; en 

这两个构造似乎是相同的:

do let x = e1
   e2

并且

do x <- e1
   e2

都评估 e1,将其绑定到 e2,然后评估 e2。

是的?

A simple question:
given the definitions, (From Haskell SOE)

   do x — el; el\ ...; en 
    => el »= \x — do e2\ ...; en 

and:

do let decllist; el\...; en 
=> let decllist in do e2\ ...; en 

it seems that these two constructs are the same:

do let x = e1
   e2

and

do x <- e1
   e2

both evaluate e1, bind it to e2, and then evaluate e2.

Yes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浅浅 2024-11-25 15:42:48

让我们在 Maybe monad 中做一个简单的例子:

foo = do
        let x = Just 1
        return x

并将

bar = do
        x <- Just 1
        return x

两者脱糖,我们得到

foo = let x = Just 1 in return x    -- do notation desugaring
    = return (Just 1)               -- let
    = Just (Just 1)                 -- definition of return for the Maybe monad

bar = let ok x = return x in Just 1 >>= ok   -- do notation desugaring
    = let ok x = return x in ok 1   -- definition of >>= for the Maybe monad
    = return 1                      -- definiton of ok
    = Just 1                        -- definition of return for the Maybe monad

作为参考,我正在使用 来自 Haskell 2010 报告第 3.14 节的翻译

Let's do a simple example in the Maybe monad:

foo = do
        let x = Just 1
        return x

and

bar = do
        x <- Just 1
        return x

Desugaring both, we get

foo = let x = Just 1 in return x    -- do notation desugaring
    = return (Just 1)               -- let
    = Just (Just 1)                 -- definition of return for the Maybe monad

bar = let ok x = return x in Just 1 >>= ok   -- do notation desugaring
    = let ok x = return x in ok 1   -- definition of >>= for the Maybe monad
    = return 1                      -- definiton of ok
    = Just 1                        -- definition of return for the Maybe monad

For reference, I am using the translation from section 3.14 of the Haskell 2010 Report.

极致的悲 2024-11-25 15:42:48

不,它们不一样。例如,

do let x = getLine
   print x

转换为

let x = getLine in print x

这是一个类型错误,因为 x 将具有 IO String 类型。我们要求打印计算本身,而不是其结果。


do x <- getLine
   print x

翻译为

getLine >>= \x -> print x

这里,x 被绑定为计算结果,其类型为 String,因此此类型进行检查。


在 do 表示法中,let 只是像往常一样将值绑定到名称,而 <- 用于执行单子绑定,即将名称绑定到计算的结果

No, they are not the same. For example,

do let x = getLine
   print x

translates to

let x = getLine in print x

this is a type error, as x will have the type IO String. We're asking to print the computation itself, not its result.


do x <- getLine
   print x

translates to

getLine >>= \x -> print x

Here x is bound as the result of the computation and its type is String, so this type checks.


In do-notation, let just binds values to names like it always does, while <- is used to perform monadic binding, which is binding a name to the result of a computation.

行雁书 2024-11-25 15:42:48

假设e1Monad m =>类型的计算m a,那么 let x = e1x <- e1 意味着有些不同的东西。

let 版本中,当您在 do 表达式中使用 x 时,您正在处理 Monad m =>; 类型的值。 m a..

在另一个版本中,当您在 do 表达式中使用 x 时,您正在处理 a 类型的值(因为 do 表示法隐式处理 monad 上的映射)。

例如:

e :: IO Int
f :: Int -> Int

-- the following will result in a type error, since f operates on `Int`, not `IO Int`:
g = do let x = e
       return $ f x

-- the following will work:
g' = do x <- e
        return $ f x

Assuming e1 is a computation of type Monad m => m a, then let x = e1 and x <- e1 mean somewhat different things.

In the let-version, when you use x within a do-expression, you are dealing with a value of type Monad m => m a.

In the other version, when you use x within a do expression, you are dealing with a value of type a (since do-notation implicitly handles mapping over the monad).

For example:

e :: IO Int
f :: Int -> Int

-- the following will result in a type error, since f operates on `Int`, not `IO Int`:
g = do let x = e
       return $ f x

-- the following will work:
g' = do x <- e
        return $ f x
倒数 2024-11-25 15:42:48

否。x <- e1 会翻译为 e1 >>= \x ->,这是一个不完整的表达式; let 表达式只是一个普通的 let。或者你想问 let(>>=) 是否是同一件事?它们非常不是:(>>=) 将 monad 包装的东西暴露给函数,该函数必须生成 monad 包装的东西。换句话说,对于 x <- e1,对于某些 ae1 的类型必须是 IO a ,但是 let x = e1 e1 的类型只是 a;在这两种情况下,x 的类型均为 a

No. x <- e1 translates to e1 >>= \x ->, an incomplete expression; the let expression is just a normal let. Or are you asking if let and (>>=) are the same thing? They very much aren't: (>>=) exposes the thing wrapped by a monad to a function, which must produce something wrapped in the monad. In other words, with x <- e1, e1's type must be IO a for some a, but with let x = e1 e1's type is just a; in both cases the type of x will be a.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文