These two rules about Functor
s are fairly well-known:
Functor
if the type parameter appears contravariantlyFunctor
instanceBut if you cheat slightly, you can break the first rule. Take the Hughes list, for example:
data HList a = UnsafeHList ([a] -> [a])
pattern HList a <- UnsafeHList (($ []) -> a)
where HList a = UnsafeHList (a ++)
instance Functor HList where
fmap f (HList a) = HList (map f a)
-- instances necessary to make HList useful, but irrelevant to this example, have been omitted
As long as you make the assumption that all HList
s will be made through the smart constructor, that Functor
instance is lawful, even though a
appears contravariantly.
My question: can you use a similar technique to break the second rule? Are there any types that have two different valid Functor
instances if you assume that they'll always be made through smart constructors?
Absolutely. Suppose you have
newtype Foo a = Foo Bool
mkFoo = Foo True
Here are its two Functor
instances:
instance Functor Foo where
fmap _ (Foo x) = Foo x
instance Functor Foo where
fmap _ !_ = mkFoo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With