Reputation: 81
I'm studying Haskell and I was asked to solve this exercise:
Implement a new data type named NovoPred that should have a value constructor with the same name. Also it should have a field named runNovoPred with type Maybe a -> Bool Then, create an Functor Contravariant instance for type NovoPred
In order to solve this exercise, I've made this solution:
module Oitavo where
import Data.Functor.Contravariant
newtype NovoPred a =
NovoPred
{ runNovoPred :: Maybe a -> Bool
}
instance Contravariant NovoPred where
contramap y (NovoPred x) = NovoPred (x . y)
As you may notice, this solution doesn't work at all. Contramap
needs to have this structure: (a -> b) -> f b -> f a
, the problem is that x
function expects to receive a value that looks like Maybe b
and it is actually receiving a value b
because that is what y
function returns. Therefore, it is impossible to do x . y
, because x
expects to receive a value that doesn't match with what y
is actually returning.
So, I think I need a way to make y
function return a value of type Maybe b
. Unfortunately, I don't have a clue on how to do it since contramap
expects to receive something like a -> b
as first parameter instead of something like a -> Maybe b
(that's what I need). Could you give me a hand with that?
Upvotes: 1
Views: 156
Reputation: 80724
If you have a function y :: a -> b
and you need to convert a Maybe a
to a Maybe b
, you can just fmap
over Maybe
:
contramap y (NovoPred x) = NovoPred (x . fmap y)
Upvotes: 5