要使用deriving Functor
,您必须启用DeriveFunctor
语言扩展并将其应用于具有协变终类型变量的多态类型 - 换句话说,一种允许有效Functor
实例的类型。然后它将派生“显而易见”的Functor
实例。
过去曾经有人担心派生的实例不如手写的实例高效,尽管我无法找到相关材料。
该算法本身是在2007年由Twan Van Laarhoven首次提出的,并且大量使用了通用Haskell编程。
实际执行任务的代码有点复杂。我认为这主要是因为早期更简单的代码有时会导致编译时间过长。Twan van Laarhoven提出了当前的代码来解决这个问题。
派生的Functor
实例总是做明显的事情。这通常没问题,但有时会错过机会。例如,假设我写了以下内容:
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
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)
可以手动编写更好的最后一种情况:
x <$ Deep pr m sf = Deep (x <$ pr) (Pair x x <$ m) (x <$ sf)
-ddump-deriv
查看实际推导出的代码。
DeriveFunctor
最初是在 GHC 6.12 中引入的,但它的发布说明并没有提供任何额外的线索。 - Cirdec