2011-03-04 56 views
4

我是一个Haskell和一个Stackoverflow noob,这里是我的 第一个&可能很基本的Haskell问题。基本的Haskell单形/多态问题(HList)

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型。这个“对齐”有技术术语吗?如果R的传递是单形性在R, 根据需要限制名单的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) 

rCons的伟大工程。但如果他们 在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

更新:如果我将它更改为'class HList l => RList r l | (r GHC.Prim.Any Int)(HCons(R GHC.Prim.Any Double)HNil)编译的UndecidableInstances和FunctionalDependencies。现在只需要弄清楚实际上的含义 – polypus74 2011-03-05 00:54:23

+0

对于函数依赖关系,“| l - > r”通常可以理解为“l唯一确定r”。这是否有助于你的直觉?另外你称之为对齐/对齐我称之为“统一”Haskell的类型系统基于“统一”(就像Prolog的评估一样)。 – 2011-03-05 08:48:56

+0

只是为了让读者放心,这不是一个noob Haskell问题。我认为这种“协调”被称为“统一”,并且这些类型被认为是“统一的”。但是这是基于类型检查器在未匹配类型时所说的,所以我可能是错的。 – 2011-03-05 14:09:59

回答

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之间的区别是,前者结合r型两个参数的同一类型的变量,后者不会:第二个参数只是l约束,因为l应该有一些RList的实例)。由于没有为rc没有类型标记(注意,如果你提供一个你原来的例子typechecks)和R1和R2具有多态性,不等同r的,编译器试图找到RList r (HCons (R r1 Double) HNil)实例的定义(r来自第一个参数和r1 - 从第二个),但没有这样做。 对于类型等价约束我们定义的rlist的实例与两个不同的r1r2,唯一的条件是,这些需求是等同的,所以它看起来像GHC的l解决的RList实例时,他们结合到同一个多态类型的变量。

+0

感谢您的提示。将在〜 – polypus74 2011-03-05 03:04:56

+0

进一步阅读:http://haskell.org/haskellwiki/GHC/Type_families – 2011-03-05 18:15:11