>>=
可以根据join :: Monad m => m (m a) -> m a
join m = m >>= id
定义实现:
join Nothing = Nothing
join (Just (Just x)) = Just x
具体来说,如何在Maybe和List单子中实现它?
可能在monad中吗?
join [] = []
join [[xs]] = [xs]
并在列表单子中:
sudo: unable to stat /etc/sudoers: Permission denied
sudo: no valid sudoers sources found, quitting
sudo: unable to initialize policy plugin
?
谢谢。
答案 0 :(得分:5)
join
仅实现一次 ,并且适用于所有Monad类型。
Monad抽象的重点是允许以相同的方式处理不同类型。一旦为您的类型提供了>>=
(和return
),并确保它们遵循Monad法则,任何通用的足以仅使用这些操作的代码都将在您的类型上正常工作。
答案 1 :(得分:4)
join
只是一个常规函数,根据预先存在的(>>=)
函数实现。您不必担心使用了哪个 monad。 (>>=)
会解决这个问题。
相反,Monad
可以的定义更接近其数学定义:
class Monad' m where
return :: a -> m a
join :: m (m a) -> m a
使用
(>>=) :: Monad' m => m a -> (a -> m b) -> m b
x >>= f = join (fmap f x)
作为常规功能。这样,join
的列表特定定义将仅为concat :: [[a]] -> [a]
:
instance Monad' [] where
return x = [x]
join = concat
答案 2 :(得分:3)
join
只是implemented as [src]:
join :: (Monad m) => m (m a) -> m a join x = x >>= id
如果我们查看[]
[src]和Maybe
[src]的monad实例,就会看到:
instance Monad [] where {-# INLINE (>>=) #-} xs >>= f = [y | x <- xs, y <- f x] {-# INLINE (>>) #-} (>>) = (*>) {-# INLINE fail #-} fail _ = []
instance Monad Maybe where (Just x) >>= k = k x Nothing >>= _ = Nothing (>>) = (*>) fail _ = Nothing
因此,对于列表,join
等效于:
-- for lists
join xs
-> xs >>= id
-> [ y | x <- xs, y <- id x ]
-> concatMap id xs
-> concat xs
因此对于列表,等效的实现是:
join_list :: [[a]] -> [a]
join_list = concat
对于Maybe
,我们可以进行案例分析:输入为Maybe (Maybe a)
,因此这里基本上存在三种可能性:
-- (1)
join Nothing
-> Nothing >>= id
-> Nothing
-- (2)
join (Just Nothing)
-> Just Nothing >>= id
-> id Nothing
-> Nothing
-- (3)
join (Just (Just x))
-> Just (Just x) >>= id
-> id (Just x)
-> Just x
因此,对于Maybe
来说,等效实现为:
join_maybe :: Maybe (Maybe a) -> Maybe a
join_maybe (Just x) = x
join_maybe Nothing = Nothing
因此, join
不会重新实现用于列表或Maybe
单子,它只是将实现用于(>>=)
用于列表和Maybe
,并且由于这些不同,join
的行为当然也不同。