[ZipList Monad] Final answer?

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? - Etsuji

On Thu, 17 Oct 2013 20:55:54 -0400 (EDT), Etsuji Nakai
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]

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]
That's right. Thanks. I found yet another pedagogical case: f x = case x of 1 -> MyZipList [1,0,0] 2 -> MyZipList [0,2,0] 3 -> MyZipList [0,0,3] otherwise -> MyZipList []
MyZipList [1,2,3] >>= f >>= f MyZipList [1,2,3]
MyZipList [1,2,3] >>= \x -> (f x >>= f) MyZipList [1]
So the conclusion is ZipList can never be a Monad in a strict sense, right? - Etsuji
participants (2)
-
Etsuji Nakai
-
Niklas Haas