我是Haskell和Stackoverflow noob,这是我的 第一&可能是相当基本的Haskell问题。
module M where
import Data.HList
data R r a
r1 = undefined :: R a Int
r2 = undefined :: R a Double
rPair :: R r a -> R r b -> (R r a, R r b)
rPair = (,)
rp = rPair r1 r2
这是有道理的,即使r1& r2在r中是多态的 rPair根据类型对齐他们的r类型 签名。这种“对齐”是否有技术术语?
class HList l => RList r l
instance RList r HNil
instance RList r l => RList r (HCons (R r a) l)
rCons :: RList r l => R r a -> l -> (HCons (R r a) l)
rCons = hCons
rc = rCons r1 (rCons r2 hNil)
如果R的传递在r中是单态的,那么rCons效果很好,
根据需要约束列表的r类型。但如果他们
r是多态的,它不像rPair那样对齐它们
是,并给出一个错误(定义上面的rc)。
No instance for (RList r (HCons (R r1 Double) HNil))
对于为什么会这样,我有一种模糊的直觉,但是 我的问题分为两部分。有人可以清楚地解释一下 现象?我怎么写这样的rCons呢? 以下会举行?
r1 = undefined :: R a Int
r2 = undefined :: R a Double
rc :: HCons (R a Int) (HCons (R a Double) HNil)
rc = rCons r1 (rCons r2 hNil)
谢谢, _c
答案 0 :(得分:1)
要回答第二个问题,您可以使用类型等价约束(来自TypeFamilies扩展名)来放宽RList
实例定义:
class HList l => RList r l
instance RList r HNil
instance (RList r1 l, r1 ~ r2) => RList r1 (HCons (R r2 a) l)
现在,您的rc
将被推断为所需的类型。
我认为我不能“清楚地解释”这种现象(有人肯定会),但很明显rPair
和rCons
之间的区别在于前者绑定{{1}同一类型变量的两个参数的类型,后者不是:第二个参数只是r
约束,l
应该有一些RList
的实例。由于l
没有类型签名(请注意,如果你提供一个原始示例的类型检查)并且r1和r2具有多态,不等同,rc
,编译器正在尝试查找r
的实例定义(RList r (HCons (R r1 Double) HNil)
来自第一个参数,r
来自第二个参数,但未能这样做。
使用类型等价约束,我们定义了一个RList实例,它有两个不同的r1
和r1
,唯一的条件就是它们必须是等价的,所以它看起来像GHC在解析时将它们绑定到相同的多态类型变量r2
的{{1}}个实例。