gpt4 book ai didi

haskell - 派生仿函数实例,而不是最后一个类型参数

转载 作者:行者123 更新时间:2023-12-02 17:50:00 24 4
gpt4 key购买 nike

相关于this question我今天早些时候问过。

我有一个包含大量案例的 AST 数据类型,它由“注释”类型参数化

data Expr ann def var = Plus a Int Int
| ...
| Times a Int Int
deriving (Data, Typeable, Functor)

我有 def 和 var 的具体实例,例如 DefVar

我想要的是自动派生 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 要求更改类型变量位于最后一个位置。只有 * -> * 类型的类型构造函数才能拥有 Functor 实例,而您的 Expr 没有这种类型。

你真的需要一个Functor实例吗?如果您只是想避免编写类似 fmap 的函数的样板,那么像 SYB 这样的解决方案是更好的解决方案(但实际上样板并没有那么糟糕,您只需编写一次)。

如果您出于其他原因需要 Functor(也许您想在具有 Functor 约束的某个函数中使用此数据结构),您必须选择是否您希望实例或类型变量按当前顺序排列。

关于haskell - 派生仿函数实例,而不是最后一个类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27674348/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com