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

发布于 2024-10-20 03:45:10 字数 1047 浏览 1 评论 0原文

我是 Haskell 和 Stackoverflow 菜鸟,这是我的 第一&可能是非常基本的 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

I'm a Haskell and a Stackoverflow noob, and here's my
first & probably quite basic Haskell question.

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

This makes sense, even if r1 & r2 are polymorphic in r
rPair aligns their r type in accordance with the type
signature. Is there a technical term for this 'alignment'?

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 works great if the R's passed are monomorphic in r,
constraining the list's r type as desired. but if they
are polymorphic in r it does not align them the way rPair
does, and gives an error (defining rc above).

No instance for (RList r (HCons (R r1 Double) HNil))

I have a vague intuition as to why this is the case, but
my question is in two parts. Could somebody clearly explain
the phenomenon? How would I write an rCons such that the
following would hold?

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)

Thanks,
_c

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

感受沵的脚步 2024-10-27 03:45:10

要回答第二个问题,您可以使用类型等效约束(来自 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 之间的区别在于,前者绑定两个参数的 r 类型为同一类型变量,后者则不然:第二个参数只是 l 约束,应该有一些 RList 实例 表示 l)。由于 rc 没有类型签名(请注意,如果您提供原始示例类型检查),并且 r1 和 r2 具有多态性,不等价r 的,编译器正在尝试查找 RList r (HCons (R r1 Double) HNil) 的实例定义(r 来自第一个参数,r1 - 从第二个开始)并且未能这样做。
通过类型等效约束,我们定义了一个具有两个不同的 r1r2 的 RList 实例,唯一的条件是它们需要等效,因此看起来 GHC 将它们绑定到解析 lRList 实例时相同的多态类型变量。

To answer your second question, you can use type equivalence constraint (from TypeFamilies extension) to relax your RList instance definition:

class HList l => RList r l
instance RList r HNil
instance (RList r1 l, r1 ~ r2) => RList r1 (HCons (R r2 a) l)

Now your rc will be inferred to the desired type.

I don't think I can 'clearly explain' the phenomenon though (somebody surely will), but it's obvious that the difference between rPair and rCons is that while the former binds r type of both arguments to the same type variable, the later doesn't: the second argument is just l constrained with that there should be some instance of RList for that l). Since there is no type signature for rc (note that if you provide one your original example typechecks) and r1 and r2 have polymorphic, not equivalent, r's , compiler is trying to find an instance definition for RList r (HCons (R r1 Double) HNil) (r comes from the 1st argument and r1 - from the 2nd) and fails to do so.
With type equivalence constraint we define an instance of RList with two distinct r1 and r2 with the only condition that these needs to be equivalent, so it looks like GHC binds them to the same polymorphic type variable when resolving instance of RList for l.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文