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

时间:2013-12-02 20:15:29

标签: haskell functor

我正在试图找出Haskell中deriving Functor的确切规则。

我已经看到了message postings,我已经看到了test code,但我似乎无法找到有关规则的官方文档。有人可以澄清和/或指引我到正确的地方吗?

2 个答案:

答案 0 :(得分:12)

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

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

据我所知,算法本身是first proposed by Twan Van Laarhoven in 2007并且大量使用Generic Haskell编程。

答案 1 :(得分:2)

不幸的是,实际行动的代码有点毛茸茸的一面。我认为这很大程度上是因为更早,更简单的代码有时会导致编译时间过长。 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

这将产生(在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)

可以手工编写最后一个案例:

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

您可以使用-ddump-deriv查看实际的派生代码。