If you make the instance listed for the first example, where the Applicative
instance has pure = repeat
and <*> = zapp
instance Applicative [] where
pure = repeat
(<*>) = zapp
transpose :: [[a]] -> [[a]]
transpose [] = pure []
transpose (xs : xss) = pure (:) <*> xs <*> transpose xss
main = do
print . transpose $ [[1,2,3],[4,5,6]]
You get the transposition from transpose:
[[1,4],[2,5],[3,6]]
If, instead, you use the normal Applicative
instance for []
instance Applicative [] where
pure x = [x]
fs <*> xs = [f x | f <- fs, x <- xs]
transpose :: [[a]] -> [[a]]
transpose [] = pure []
transpose (xs : xss) = pure (:) <*> xs <*> transpose xss
main = do
print . transpose $ [[1,2,3],[4,5,6]]
You get
[[1,4],[1,5],[1,6],[2,4],[2,5],[2,6],[3,4],[3,5],[3,6]]
The boilerplate for both of those examples is:
module Main (
main
) where
import Prelude hiding (repeat)
infixl 4 <*>
class Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
repeat :: a -> [a]
repeat x = x : repeat x
zapp :: [a -> b] -> [a] -> [b]
zapp (f : fs) (x : xs) = f x : zapp fs xs
zapp _ _ = []