【发布时间】:2016-10-27 20:44:26
【问题描述】:
假设定义了以下数据类型:
data X a = X {getX :: a}
data Y a = Y {getY :: a}
data Z a = Z {getZ :: a}
必须有三个独立的函数,getX、getY 和 getZ?在我看来,可能有一个函数定义如下:
get :: forall (τ :: (* -> *)) (a :: *). τ a -> a
get (_ x) = x
显然这不是有效的标准 Haskell,但是 GHC 有很多扩展,看起来他们可能有解决方案(RankNTypes、ExistentialQuantification、DataKinds 等)。除了避免少量键入的简单原因之外,还有避免记录解决方案产生的命名空间污染的好处。我想这实际上只是一个比使用这样的类型类更隐含的解决方案:
class Get f where
get :: f a -> a
但是,定义泛型函数似乎比类型类更有用,因为它是隐式定义的,这意味着它可以在更多地方使用,就像 ($) 或 @987654331 @ 用来。所以我的问题分为三个部分:有没有办法做到这一点,这是一个好主意,如果没有,有什么更好的方法?
【问题讨论】:
-
如果你的
get函数有一个列表(也就是说,如果τ是[]),你的get函数会做什么? -
好吧,它做了一个不可行的隐含假设。没有理由假设具有类型 * 的最终类型变量的类型具有单个构造函数,该构造函数接受所讨论类型的单个参数。
标签: haskell types data-kinds