Haskell 修复代数数据类型的重复实例声明
假设我有一个代数数据类型Haskell 修复代数数据类型的重复实例声明,haskell,algebraic-data-types,Haskell,Algebraic Data Types,假设我有一个代数数据类型Building: 数据构建 =啤酒餐厅 |商店 |布豪斯之家酒店 ... 餐厅,商店,房子。。。所有实例都是某个类。现在让我们使用Show。我目前正在将构建的显示实例定义为: 实例显示建筑位置 show(BRestaurant a)=show a 显示(b存储a)=显示a 显示(B房屋a)=显示a ... 这似乎很重复在知道每个元素实例都会显示并且每个构造函数只有一个参数的情况下,是否有方法将show函数应用于内部数据?我是否遗漏了其他一些可以减少重复性的内容?理想
Building
:
数据构建
=啤酒餐厅
|商店
|布豪斯之家酒店
...
餐厅
,商店
,房子
。。。所有实例都是某个类。现在让我们使用Show
。我目前正在将构建
的显示
实例定义为:
实例显示建筑位置
show(BRestaurant a)=show a
显示(b存储a)=显示a
显示(B房屋a)=显示a
...
这似乎很重复在知道每个元素实例都会显示并且每个构造函数只有一个参数的情况下,是否有方法将show函数应用于内部数据?我是否遗漏了其他一些可以减少重复性的内容?理想情况下,我最终会得到如下结果:
instance Show Building where
show a = applyFunctionMagic show a
听起来像是泛型的一个很好的用例
{-#语言派生泛型,类型运算符#-}
进口GHC.仿制药
我们想为泛型类型实现一些过程函数:
数据构建
=啤酒餐厅
|商店
|布豪斯之家酒店
派生泛型
进程::构建->字符串
进程=gprocess。从…起
为此,我们定义了以下gprocess
函数,其中我们用一些参数fp
替换类型Building
:
class GProcess f其中
gprocess::fp->String
并为GHC.Generics中的各种类型构造函数实现它
我们总是通过M1
来提升它(当您需要访问构造函数或字段名时,此实例变得不那么琐碎):
instance GProcess f=>GProcess(M1 i c f),其中
gprocess(M1 x)=gprocess x
我们对使用(:+:)
表示的和类型感兴趣:
instance(GProcess f,GProcess g)=>GProcess(f:+:g)其中
gprocess(L1 x)=gprocess x
gprocess(r1y)=gprocess y
最后,我们用K1
处理字段:
instance Show a=>GProcess(K1 i a)其中
gprocess(K1 x)=显示x
对于每个构造函数只有一个字段的ADT来说就是这样
全部要点:
有关泛型的更多信息:
- A
- 该库是GHC.Generics的一个更简单的变体,包含更多教程
- 模块文档
听起来像是泛型的一个很好的用例
{-#语言派生泛型,类型运算符#-}
进口GHC.仿制药
我们想为泛型类型实现一些过程函数:
数据构建
=啤酒餐厅
|商店
|布豪斯之家酒店
派生泛型
进程::构建->字符串
进程=gprocess。从…起
为此,我们定义了以下gprocess
函数,其中我们用一些参数fp
替换类型Building
:
class GProcess f其中
gprocess::fp->String
并为GHC.Generics中的各种类型构造函数实现它
我们总是通过M1
来提升它(当您需要访问构造函数或字段名时,此实例变得不那么琐碎):
instance GProcess f=>GProcess(M1 i c f),其中
gprocess(M1 x)=gprocess x
我们对使用(:+:)
表示的和类型感兴趣:
instance(GProcess f,GProcess g)=>GProcess(f:+:g)其中
gprocess(L1 x)=gprocess x
gprocess(r1y)=gprocess y
最后,我们用K1
处理字段:
instance Show a=>GProcess(K1 i a)其中
gprocess(K1 x)=显示x
对于每个构造函数只有一个字段的ADT来说就是这样
全部要点:
有关泛型的更多信息:
- A
- 该库是GHC.Generics的一个更简单的变体,包含更多教程
- 模块文档
考虑到作者所写的“暂时让我们使用Show”,问题可能不是关于Show
。考虑到作者所写的“暂时让我们使用Show”,问题可能不是关于Show
。这真的很酷!如果我想为多个类实例化Building
,我是否应该向GProcess
添加另一个参数来指定返回类型(例如GProcess f r其中GProcess::f p->r
)?然后,当我为Show
实例时,我会将返回类型指定为String(必要时使用newtype)?当然,这是一种可能的泛化。这真的很酷!如果我想为多个类实例化Building
,我是否应该向GProcess
添加另一个参数来指定返回类型(例如GProcess f r其中GProcess::f p->r
)?然后,当我为Show
实例它时,我会将返回类型指定为String(必要时使用newtype)?当然,这是一种可能的泛化。