带有键入/球拍的有界参数化类型

时间:2015-04-27 14:27:16

标签: generics bounded-wildcard typed-racket

假设我有一个函数在base类型的值上运行并返回base类型的值:

(struct base ([x : Real]))
(struct child base ([y : String]))

(: fun (base base → base))
(define (fun a b)
  (if (> (base-x a) (base-x b))
      a
      b))

函数fun也可以限制为child类型,在这种情况下,它可以保证返回类型child的值(不修改代码):

(: fun (child child → child))

还可以让它接受basechild值,并返回相同的类型:

(: fun (case→ (base base → base)
              (child child → child)))

这缺乏界限,并且由于显而易见的原因而失败:

(: fun (All (T) (T T → T)))

如果有child个类型,通过提供All的绑定,我该如何简化?

我正在寻找类似于这个的语法:

(: fun (All (T : base) (T T → T)))

1 个答案:

答案 0 :(得分:1)

不直接支持,但在latest snapshot versions中,可以使用intersection types来模拟它:

(: fun : (All (T) ((∩ base T) (∩ base T) → (∩ base T))))

然后fun会在给定basechild类型的混合时返回最具体的类型:

> (fun (base 1) (base 2))
- : base
#<base>
> (fun (base 1) (child 2 "string"))
- : base
#<child>
> (fun (child 1 "string") (base 2))
- : base
#<base>
> (fun (child 1 "string") (child 2 "string"))
- : (∩ child base)
#<child>
> (ann (fun (child 1 "string") (child 2 "string")) child)
- : child
#<child>

您可以在期望(∩ child base)

的上下文中使用child