Haskell Monadic 形式
一个简单的问题: 给定定义,(来自 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
让我们在
Maybe
monad 中做一个简单的例子:并将
两者脱糖,我们得到
作为参考,我正在使用 来自 Haskell 2010 报告第 3.14 节的翻译。
Let's do a simple example in the
Maybe
monad:and
Desugaring both, we get
For reference, I am using the translation from section 3.14 of the Haskell 2010 Report.
不,它们不一样。例如,
转换为
这是一个类型错误,因为
x
将具有IO String
类型。我们要求打印计算本身,而不是其结果。翻译为
这里,
x
被绑定为计算结果,其类型为String
,因此此类型进行检查。在 do 表示法中,let 只是像往常一样将值绑定到名称,而
<-
用于执行单子绑定,即将名称绑定到计算的结果。No, they are not the same. For example,
translates to
this is a type error, as
x
will have the typeIO String
. We're asking to print the computation itself, not its result.translates to
Here
x
is bound as the result of the computation and its type isString
, 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.假设
e1
是Monad m =>类型的计算m a
,那么let x = e1
和x <- e1
意味着有些不同的东西。在
let
版本中,当您在 do 表达式中使用x
时,您正在处理Monad m =>; 类型的值。 m a.
.在另一个版本中,当您在 do 表达式中使用 x 时,您正在处理 a 类型的值(因为 do 表示法隐式处理 monad 上的映射)。
例如:
Assuming
e1
is a computation of typeMonad m => m a
, thenlet x = e1
andx <- e1
mean somewhat different things.In the
let
-version, when you usex
within a do-expression, you are dealing with a value of typeMonad m => m a
.In the other version, when you use
x
within a do expression, you are dealing with a value of typea
(since do-notation implicitly handles mapping over the monad).For example:
否。
x <- e1
会翻译为e1 >>= \x ->
,这是一个不完整的表达式;let
表达式只是一个普通的let
。或者你想问let
和(>>=)
是否是同一件事?它们非常不是:(>>=)
将 monad 包装的东西暴露给函数,该函数必须生成 monad 包装的东西。换句话说,对于x <- e1
,对于某些a
,e1
的类型必须是IO a
,但是let x = e1
e1
的类型只是a
;在这两种情况下,x
的类型均为a
。No.
x <- e1
translates toe1 >>= \x ->
, an incomplete expression; thelet
expression is just a normallet
. Or are you asking iflet
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, withx <- e1
,e1
's type must beIO a
for somea
, but withlet x = e1
e1
's type is justa
; in both cases the type ofx
will bea
.