"派生函数"到底是做什么的?

Ana*_*Ana 22 haskell functor

我想弄清楚deriving FunctorHaskell的确切规则是什么.

我已经看到有关它的消息发布,我已经看到有关它的测试代码,但我似乎无法找到有关规则的官方文档.有人可以澄清和/或指出我到正确的地方吗?

J. *_*son 12

要使用deriving Functor,必须启用DeriveFunctor语言编译指示并将其应用于具有协变最终类型变量的多态类型 - 换句话说,即允许有效Functor实例的类型.然后它将导出"明显的" Functor实例.

过去有人担心派生的实例不像手工编写的那样有效,尽管我似乎无法找到那些材料.

据我所知,该算法本身是由Twan Van Laarhoven在2007年首次提出并大量使用Generic Haskell编程.


dfe*_*uer 6

不幸的是,实际执行此操作的代码有点复杂。我认为这主要是因为早期、更简单的代码有时会导致编译时间过长。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。