与this question相关我今天早些时候问过。派生函数实例,而不是最后一个参数
我有大量的案例,这是由“注释”型
data Expr ann def var = Plus a Int Int
| ...
| Times a Int Int
deriving (Data, Typeable, Functor)
我有具体事例为高清和VAR参数的AST数据类型,说Def
和Var
。
我想要的是自动派生fmap
作为第一个参数仿函数。我想获得一个功能,看起来像这样:
fmap :: (a -> b) -> (Expr a Def Var) -> (Expr b Def Var)
当我正常使用fmap
,我收到表示FMAP试图它的功能应用到最后一类的说法,也不是第一个编译器的消息。
有没有一种方法,我可以派生所描述的功能,而不写一堆样板?我试着这样做:
newtype Expr' a = E (Expr a Def Var)
deriving (Data, Typeable, Functor)
,但我得到了以下错误:
Constructor `E' must use the type variable only as the last argument of a data type
我与别人的代码基础工作,所以这将是理想的,如果我没有切换无处不在的类型参数的顺序。
,可以定义不同的,相同类型,在该类型参数你可以做一个丑陋的黑客正确的顺序,为其派生Functor实例,然后在其上使用'unsafeCoerce'。这真的很糟糕,我不推荐它。最简单的选择是推出自己的派生功能;或者干脆重构现有的代码。如果您不介意拉大依赖性,请查看[derive](http://hackage.haskell.org/package/derive-2.5.5/docs/Data-Derive-Functor.html)包。 – user2407038
'Expr ann def'不能有'Functor'实例,除非'var'是用'fmap'改变的类型变量。 – Cirdec
对于hask包来说,没有'DeriveFunctor'类型的功能是很遗憾的。 'hask'包提供了一个polykinded'Functor'类的类,它可以通过类型变量比第一个变量更深(只要所有类型变量右边有'Functor'实例也是如此,在这种情况下,这听起来像是微不足道的)。 –