在 Haskell 中为列表 monad 定义 bind without join

Define bind without join for the list monad in Haskell

我理解 >>= 的定义 join

xs >>= f = join (fmap f xs)

这也告诉我们 fmap + join 产生 >>=

我想知道对于 List monad 是否可以在没有 join 的情况下定义,就像我们为 Maybe:

所做的那样
>>= m f = case m of
    Nothing -> Nothing
    Just x  -> f x

当然可以。 GHC/Base.hs 中的实际定义是根据等效列表理解:

instance Monad []  where
    xs >>= f             = [y | x <- xs, y <- f x]

或者,您可以尝试使用以下方法从头开始计算类型:

(>>=) :: [a] -> (a -> [b]) -> [b]

我们需要处理两种情况:

[] >>= f = ???
(x:xs) >>= f = ???

第一个很简单。我们没有 a 类型的元素,因此我们无法应用 f。我们唯一能做的就是return一个空列表:

[] >>= f = []

对于第二个,x 是一个 a 类型的值,所以我们可以应用 f 给我们一个 f x 类型的值 [b].这是我们列表的开头,我们可以将它与递归调用生成的列表的其余部分连接起来:

(x:xs) >>= f = f x ++ (xs >>= f)