在monad的上下文中一定要使用符号吗? [英] Is do notation used necessarily in the context of monad?

查看:97
本文介绍了在monad的上下文中一定要使用符号吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

2010年哈斯克尔报告说

Haskell report 2010 says

do表达式为提供了一种更常规的monadic语法 编程.它允许一个表达式,例如

A do expression provides a more conventional syntax for monadic programming. It allows an expression such as

putStr "x: " >>
getLine >>= \l ->
return (words l)

用更传统的方式写成:

do putStr "x: "
   l <- getLine
   return (words l)

汤普森(Halfell)的汤普森(Halfell)的函数式编程技巧

Haskell the Craft of Functional programming by Thompson says

我们将继续使用do表示法,但请记住,它本质上是 归结为一个函数(>> =)的存在,该函数负责对I/O进行排序 程序,并将其结果绑定起来以备将来使用.

We'll continue to use the do notation, but will keep in mind that it essentially boils down to the existence of a function (>>=) which does the work of sequencing I/O programs, and binding their results for future use.

上面的意思是否意味着必须在monad的上下文中使用符号?

Do the above mean that do notation is used necessarily in the context of monad?

如果是,为什么以下函子使用do表示法?

If yes, why does the following functor use the do notation?

instance    Functor IO  where
    --  fmap    ::  (a  ->  b)  ->  IO  a   ->  IO  b
    fmap    g   mx  =   do  {x  <-  mx; return  (g  x)}

推荐答案

是.正如文章所引用的那样,对于单键运算,do-表示法只是 语法糖 .

这些是规则,用于对do标记进行除糖:

These are the rules for de-sugaring do-notation:

  1. do {foobar; ...} = foobar >> do {...}(又名foobar >>= \_ -> do {...})
  2. do {a <- foobar; ...} = foobar >>= \a -> do {...}
  3. do {foobar} = foobar
  1. do {foobar; ...} = foobar >> do {...} (aka foobar >>= \_ -> do {...})
  2. do {a <- foobar; ...} = foobar >>= \a -> do {...}
  3. do {foobar} = foobar

这必然意味着do-表示法完全适用于monad,除非规则3所描述的琐碎情况.

Necessarily this means that do-notation works entirely on monads, except in the trivial case that rule 3 describes.

例如,如文章所述,do {putStr "x: "; l <- getLine; return (words l)}等于putStr "x: " >> (getLine >>= \l -> return (words l)),您可以通过除糖规则进行确认.

So for instance, as the article states, do {putStr "x: "; l <- getLine; return (words l)} is exactly equal to putStr "x: " >> (getLine >>= \l -> return (words l)), which you may confirm via the de-sugaring rules.

在上面引用的Functor IO的定义中,已经定义了Monad IO实例,因此我们也使用它来定义Functor实例.

In the definition for Functor IO you quote above, the Monad IO instance has already been defined, and so we are using it to define the Functor instance, too.

注意到所有monad一定是函子(请参阅

It may also be useful to note that all monads are necessarily functors (see the definition of the Monad typeclass), so when one says do-notation works on monads, it also necessarily works on the functors as well. I suspect this may be a point of confusion.

值得注意的是,在某些受限情况下,可能仅使用Applicative操作,而不是更通用的Monad操作.例如,文章提供的示例可以写为putStr "x: " *> (pure words <*> getLine).有一个名为 ApplicativeDo 的实验语言扩展,它已添加到GHC能够识别这些情况并将do-标记的某些情况推广到所有应用程序,而不仅是所有monads的能力.

It is worth noting that in certain restricted cases, it is possible to use only Applicative operations rather than the more general Monad operations. For instance, the example the article provides could be written as putStr "x: " *> (pure words <*> getLine). There is an experimental language extension called ApplicativeDo which adds to GHC the capability to recognise these situations and generalise certain cases of do-notation to all applicatives, not just all monads.

这篇关于在monad的上下文中一定要使用符号吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆