基本的Haskell单态/多态问题(HList)

时间:2011-03-04 23:54:32

标签: haskell polymorphism monomorphism hlist

我是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

1 个答案:

答案 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将被推断为所需的类型。

我认为我不能“清楚地解释”这种现象(有人肯定会),但很明显rPairrCons之间的区别在于前者绑定{{1}同一类型变量的两个参数的类型,后者不是:第二个参数只是r约束,l应该有一些RList的实例。由于l没有类型签名(请注意,如果你提供一个原始示例的类型检查)并且r1和r2具有多态,不等同rc,编译器正在尝试查找r的实例定义(RList r (HCons (R r1 Double) HNil)来自第一个参数,r来自第二个参数,但未能这样做。 使用类型等价约束,我们定义了一个RList实例,它有两个不同的r1r1,唯一的条件就是它们必须是等价的,所以它看起来像GHC在解析时将它们绑定到相同的多态类型变量r2的{​​{1}}个实例。