[Haskell-cafe] [ZipList Monad] Final answer?

Niklas Haas haskell at nand.wakku.to
Fri Oct 18 13:43:50 UTC 2013


On Thu, 17 Oct 2013 20:55:54 -0400 (EDT), Etsuji Nakai <enakai at redhat.com> wrote:
> Hi,
> 
> I found a few interesting discussions on how to construct ZipList Monad in the past (around 2009). 
> 
> For example, http://www.haskell.org/pipermail/haskell-cafe/2009-April/059079.html
> 
> But there seems no final answer to it. After a good discussion with one of my Haskell friends, we finally came up with the following one:
> 
> 
> import Control.Monad
> newtype MyZipList a = MyZipList [a] deriving (Show)
> 
> getBase :: MyZipList a -> [a]
> getBase (MyZipList xs) = xs
> 
> instance Monad MyZipList where
>   return x = MyZipList $ repeat x
>   m >>= f  = MyZipList $ bind (getBase m) (fmap getBase f)
>     where
>       bind :: [a] -> (a -> [b]) -> [b]
>       bind [] f     = []
>       bind (x:xs) f = case f x of
>                         [] -> []
>                         y:_ -> y : bind xs (fmap tailOrNil f)
>       tailOrNil :: [b] -> [b]
>       tailOrNil []     = []
>       tailOrNil (x:xs) = xs
> 
> 
> This is fairly simple and looks to work with variable length lists. Do you think this could be the final answer?

Violates the Monad laws, specifically join . join = join . fmap join:

>>> let join x = bind x id
>>> join (join [[[1]],[[],[2,3]]])
[1,3]
>>> join (fmap join [[[1]],[[],[2,3]]])
[1]


More information about the Haskell-Cafe mailing list