'return' 关键字有什么特别之处 [英] What's so special about 'return' keyword
问题描述
当我似乎理解了 Haskell 中的 return 是什么时,我尝试使用不同的替代方案,似乎 return 不仅可以在 monad 链中的任何地方使用,而且可以完全排除
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
即使我在自己的实例中省略了 return,我也只会收到警告...
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'
而且我仍然可以使用 monad
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
那么 return 关键字有什么特别之处呢?这是关于我不能省略它的更复杂的情况吗?还是因为即使可以以不同的方式做事,这也是正确"的做事方式?
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?
更新:.. 或另一种选择,我可以定义自己的 monadic 值构造函数
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
推荐答案
那么 return 关键字有什么特别之处呢?
So what's so special about the return keyword?
首先,return
不是 Haskell 中的关键字.它是一个重载函数.
Firstly, return
is not a keyword in Haskell. It is an overloaded function.
它的类型由以下给出:
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
所以你看到 return
是一个函数,它给定一个 a
类型的值,返回一个 ma
类型的新值,其中 m
是某种类型,它是 Monad
的一个实例.此类类型包括:
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
也许
- Monad
STM
- Monad
((->) r)
- Monad
(Either e)
- Monad
(ST s)
还有更多.'Monad' 的实例应满足以下规律:
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
一个函数的实现a ->m a
很容易猜到.以下是最常见的 monad 的定义:
The implementation of a function a -> m a
is pretty easy to guess. Here's the definition for the most common monads:
列表:
return x = [x]
也许
return x = Just x
所以你看到 return
是一个重载函数,它将一个值提升"到一个 monadic 包装器中.因此,您可以在任何可以使用其定义的地方使用它.例如
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]
或在 do
概念(当
> do v <- return 7 ; return v :: Maybe Int
Just 7
使用 monadic return
的真正原因是在一些 monad 中组合多个值:
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
在最后一条语句中,您可以看到当给定的 monad 达到零值时,链是如何短路的.在这种情况下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
.
总结:return
是一个重载函数,它将一个值提升到一个 monadic 包装器中.当您需要提升价值时,您可以使用它.它不是控制流关键字,因为它是命令式语言.
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屋!