J. *_*son 12
要使用deriving Functor,必须启用DeriveFunctor语言编译指示并将其应用于具有协变最终类型变量的多态类型 - 换句话说,即允许有效Functor实例的类型.然后它将导出"明显的" Functor实例.
过去有人担心派生的实例不像手工编写的那样有效,尽管我似乎无法找到那些材料.
据我所知,该算法本身是由Twan Van Laarhoven在2007年首次提出并大量使用Generic 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
Run Code Online (Sandbox Code Playgroud)
这将生成(在 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)
Run Code Online (Sandbox Code Playgroud)
最后一个例子可以用手写得更好:
x <$ Deep pr m sf = Deep (x <$ pr) (Pair x x <$ m) (x <$ sf)
Run Code Online (Sandbox Code Playgroud)
您可以使用查看实际的派生代码-ddump-deriv。