outer :: (Functor l, Functor r) => (a->b->c) -> l a -> r b -> l (r c)
We replace the list constructors []
with functors. The result nests two functors—note that we now keep track of which is which.
λ> let outer f x y = fmap (\a -> fmap (f a) y) x λ> outer (*) [1,2,3] (Just 3) [Just 3,Just 6,Just 9] λ> outer (*) [1,2,3] Nothing [Nothing,Nothing,Nothing]
λ> (outer (\a b -> [a,b]) (1+) (2*)) 3 4 [4,8]