Consider a Users type with two parameters, a and b. Clearly, this enables User to be composed of two different types:
data Users a b = User a b deriving (Show, Eq, Ord)
How can we declare functors and applicative for this instance?
I've tried these approaches won't compile:
instance Functor Users where
fmap f(User a b) = User (f a) (f b)
instance Applicative Users where
pure a b = User a b
(<*>) User a b = (fmap a) (fmap b)
What's the reason these won't compile?
Have a look at Data.Bifunctor
for a type class for ADTs which are functorial in both arguments. User
is then just a fancy name for tuple, and this already supports such an instance. Deriving a bifunctor instance is possible in Haskell.
@Bakuriu suggests defining User
as a newtype
and the using the extension GeneralizedNewtypeDeriving
.
For the second one, see Biapplicative
. As to be expected, its instance for (,)
is:
instance Biapplicative (,) where
pure = (,)
ap (f, g) (a, b) = (f a, g b)