Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What exactly does "deriving Functor" do?

I'm trying to figure out what exactly are the rules for deriving Functor in Haskell.

I've seen message postings about it, and I've seen test code about it, but I can't seem to find official documentation about what the rules are. Can someone please clarify and/or point me to the right place?

like image 590
Ana Avatar asked Dec 02 '13 20:12

Ana


People also ask

What does deriving show mean Haskell?

Deriving means that your data type is automatically able to "derive" instances for certain type classes. In this case BaseballPlayer derives Show which means we can use any function that requires an instance of Show to work with BaseballPlayer .

Is string a functor?

String is not a functor, because it has the wrong kind.

How do you use derivefunctor?

To use deriving Functor you must enable the DeriveFunctor language pragma and apply it to a polymorphic type which has a covariant final type variable---in other words, a type which admits a valid Functor instance. It'll then derive the "obvious" Functor instance.

What is derivefunctor in GHC?

DeriveFunctor was first introduced in GHC 6.12, but the release notes for it don't provide any additional clues. To use deriving Functor you must enable the DeriveFunctor language pragma and apply it to a polymorphic type which has a covariant final type variable---in other words, a type which admits a valid Functor instance.

What version of derivefunctor was first introduced?

Can someone please clarify and/or point me to the right place? DeriveFunctor was first introduced in GHC 6.12, but the release notes for it don't provide any additional clues.


2 Answers

To use deriving Functor you must enable the DeriveFunctor language pragma and apply it to a polymorphic type which has a covariant final type variable---in other words, a type which admits a valid Functor instance. It'll then derive the "obvious" Functor instance.

There's been some concern in the past that the derived instance is not as efficient as a hand coded one is, though I cannot seem to find that material.

The algorithm itself was, as far as I could find, first proposed by Twan Van Laarhoven in 2007 and makes heavy use of Generic Haskell programming.

like image 188
J. Abrahamson Avatar answered Sep 20 '22 16:09

J. Abrahamson


The code that actually does the deed is, unfortunately, a bit on the hairy side. I believe that's largely because earlier, simpler code would sometimes lead to excessive compilation times. Twan van Laarhoven came up with the current code to address this.

The derived Functor instance always does the obvious thing. This is usually just fine, but occasionally misses opportunities. For example, suppose I write

data Pair a = Pair a a deriving Functor data Digit a = One a | Two a a deriving Functor data Queue a =     Empty   | Single a   | Deep !(Digit a) (Queue (Pair a)) !(Digit a) deriving Functor 

This will generate (in GHC 8.2)

instance Functor Queue where   fmap ...   x <$ Empty = Empty   x <$ Single y = Single x   x <$ Deep pr m sf = Deep (x <$ pr) (fmap (x <$) m) (x <$ sf) 

It's possible to write that last case much better by hand:

  x <$ Deep pr m sf = Deep (x <$ pr) (Pair x x <$ m) (x <$ sf) 

You can see the actual derived code using -ddump-deriv.

like image 34
dfeuer Avatar answered Sep 21 '22 16:09

dfeuer