我正在试图找出Haskell中deriving Functor
的确切规则。
我已经看到了message postings,我已经看到了test code,但我似乎无法找到有关规则的官方文档。有人可以澄清和/或指引我到正确的地方吗?
答案 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
查看实际的派生代码。