I am reading the great post from Bartosz Milewski about Products and Coproducts.
Consider following functions:
factorizer :: (c -> a) -> (c -> b) -> (c -> (a, b))
factorizer p q = \x -> (p x, q x)
Is (c -> (a, b))
the factorizer? If yes, why? Honestly, for me the sample is just a function, that expects two higher order function. I can't see the pattern of the Product
.
The next sample:
factorizer :: (a -> c) -> (b -> c) -> Either a b -> c
factorizer i j (Left a) = i a
factorizer i j (Right b) = j b
How can I recognize the pattern of Coproducts
corresponding to the code above?
In both cases, factorizer
is the factorizer. From the blog post:
A (higher order) function that produces the factorizing function m from two candidates is sometimes called the factorizer.
The pattern is that in both cases these functions give the only solution to certain equations.
For products, for every f
and g
, factorizer f g
is the only function such that fst . factorizer f g = f
and snd . factorizer f g = g
.
For coproducts, for every f
and g
, factorizer f g
is the only function such that factorizer f g . Left = f
and factorizer f g . Right = g
.
The existence of factorizers characterizes the Either
and (,)
types up to isomorphism. That provides an alternative way of describing products and sums that can be generalized to other categories (it's only about composition of morphisms). In contrast, a definition by data (,) a b = (,) a b
and data Either a b = Left a | Right b
is ad-hoc to a particular language.