'return'关键字有什么特别之处 [英] What's so special about 'return' keyword

查看:84
本文介绍了'return'关键字有什么特别之处的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我似乎明白Haskell有什么回报时,我尝试着使用不同的选择,并且它似乎不仅可以在monad链中的任何地方使用,而且可以完全排除。

  * Main>只是9>> = \ y  - > (Just y)>> = \ x  - >返回x 
只需9

*主要>只是9>> = \ y - > (返回y)>> = \ x - > (只是)
只需9

*主要>只是9>> = \ y - > (Just y)>> = \ x - > (只是x)
只是9

即使我在自己的实例中省略了回报,只会得到警告......

 数据MaybeG a = NothingG | JustG a派生Show 
实例Monad MaybeG其中
- return x = JustG x
NothingG>> = f = NothingG
JustG x>> = f = fx
失败_ = NothingG

Monad.hs:3:10:
警告:没有明确的方法也没有默认的`return'方法
在` Monad MaybeG'

我仍然可以使用monad

  * Main> JustG 9>> = \ y  - > (JustG 11)>> = \ x  - > (只是)
只是9

*主要> JustG 9>> = \ y - > (NothingG)>> = \ x - > (JustGy)
NothingG

那么return关键字有什么特别的地方呢?这是关于更复杂的情况下,我不能忽略它吗?或者因为这是做事的正确方式,即使他们可以以不同的方式完成工作?



更新:
..或另一种选择,我可以定义我自己的monadic值构造函数

  finallyMyLastStepG :: Int  - > MaybeG Int 
finallyMyLastStepG a = JustG a

并生成同一链的另一个变体(with相同的结果)

  * Main> JustG 9>> = \ y  - > (JustG 11)>> = \ x  - > (finallyMyLastStepG y)
JustG 9


解决方案


那么return关键字有什么特别的地方呢?


首先, return 不是关键字在Haskell。它是一个重载函数。



它的类型如下:

  class Monad m其中
- |按顺序组成两个动作,将任何产生的
值 - 第一个作为参数传递给第二个动作。
(>> =):: m a - > (a - > m b) - > m b

- |将值注入monadic类型。
return :: a - > ma

所以你看到 return 是一个函数给定 a 类型的值,返回一个新类型的值 ma ,其中 m 是一些类型,它是 Monad 的一个实例。这种类型包括:


  • Monad []

  • Monad I0

  • Monad 也许

  • Monad STM

  • Monad (( - >)r)
  • Monad (或e)

  • Monad (ST s)



以及更多内容。 Monad的实例应该满足以下法律:

 >返回a>> = k == k a 
> m>> = return == m
> (m> = k)>> = h
< / code>>< / pre>

函数 a - >的实现m a 很容易猜到。以下是最常见monads的定义:



列表

  return x = [x] 

也许

  return x =只需x 

所以你看到 return 是一个重载函数,它将一个值提升为一元包装。因此,您可以在任何可以使用其定义的地方使用它。例如:

  Prelude> 1:return 2 
[1,2]

do 概念链接表达)。

 > ;做v < - 返回7; return v :: Maybe Int 
只是7

使用monadic <$的真正原因

  Prelude> c $ c> return 是在某些monad中编写多个值时。 do x<  -  return 1; y < - 返回2; return(x + y):: Maybe Int 
只需3
Prelude>做x < - 无; y < - 返回2;返回y
没有任何

在上一个语句中,您会看到链条一旦短路为给定的monad命中一个零值。在这种情况下 Nothing



摘要: return is一个重载的函数,将一个值提升为一个monadic包装器。您在需要提升值时使用它。它是不是控制流关键字,因为它是命令式语言。


When I seemed to understand what return is for in Haskell, I tried to play with different alternatives and it seems that return not only can be used anywhere in the monad chain, but also can be excluded completely

*Main> Just 9 >>= \y -> (Just y) >>= \x -> return x
Just 9

*Main> Just 9 >>= \y -> (return y) >>= \x -> (Just y)
Just 9

*Main> Just 9 >>= \y -> (Just y) >>= \x -> (Just x)
Just 9 

Even if I omit return in my own instancing, I only get warning...

data MaybeG a = NothingG | JustG a deriving Show 
instance Monad MaybeG where  
    --    return x = JustG x  
        NothingG >>= f = NothingG  
        JustG x >>= f  = f x  
        fail _ = NothingG  

Monad.hs:3:10:
    Warning: No explicit method nor default method for `return'
    In the instance declaration for `Monad MaybeG'

and I still can use the monad

*Main> JustG 9 >>= \y -> (JustG 11) >>= \x -> (JustG y)
JustG 9

*Main> JustG 9 >>= \y -> (NothingG) >>= \x -> (JustG y)
NothingG

So what's so special about the return keyword? Is this about more complex cases where I can not omit it? Or because this is the "right" way to do things even if they can be done differently?

UPDATE: .. or another alternative, I could define my own monadic value constructor

finallyMyLastStepG :: Int -> MaybeG Int
finallyMyLastStepG a = JustG a  

and produce another variant of the same chain (with the same result)

*Main> JustG 9 >>= \y -> (JustG 11) >>= \x -> (finallyMyLastStepG y)
JustG 9

解决方案

So what's so special about the return keyword?

Firstly, return is not a keyword in Haskell. It is an overloaded function.

Its type is given by:

class  Monad m  where
    -- | Sequentially compose two actions, passing any value produced
    -- by the first as an argument to the second.
    (>>=)       :: m a -> (a -> m b) -> m b

    -- | Inject a value into the monadic type.
    return      :: a -> m a

So you see that return is a function that given a value of type a, returns a new value of type m a, where m is some type that is an instance of Monad. Such types include:

  • Monad []
  • Monad I0
  • Monad Maybe
  • Monad STM
  • Monad ((->) r)
  • Monad (Either e)
  • Monad (ST s)

and many more besides. Instances of 'Monad' should satisfy the following laws:

> return a >>= k  ==  k a
> m >>= return  ==  m
> m >>= (\x -> k x >>= h)  ==  (m >>= k) >>= h

The implementation of a function a -> m a is pretty easy to guess. Here's the definition for the most common monads:

Lists:

 return x = [x]

Maybe

 return x = Just x

So you see that the return is an overloaded function that "lifts" a value into a monadic wrapper. You can thus use it anywhere you can use its definition. E.g.

Prelude> 1 : return 2
[1,2]

or in the do notion (useful when chaining expressions).

> do v <- return 7 ; return v :: Maybe Int
Just 7

The real reason to use a monadic return is when composing multiple values in some monad:

Prelude> do x <- return 1 ; y <- return 2 ; return (x + y) :: Maybe Int
Just 3
Prelude> do x <- Nothing  ; y <- return 2 ; return y
Nothing

In the last statement you see how the chain short-circuited once it hit a zero value for the given monad. In this case Nothing.

Summary: return is an overloaded function that lifts a value into a monadic wrapper. You use it when you need to lift values. It is not a control-flow keyword, as it is in imperative languages.

这篇关于'return'关键字有什么特别之处的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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