无法应用键入的球拍多态功能

时间:2014-03-12 21:48:53

标签: types scheme racket typed-racket

> (map (λ: ([x : (Pairof Symbol Number)]) (cdr x)) (list (cons (quote a) 0.3) (cons (quote b) 0.2) (cons (quote c) 0.5)))
- : (Listof Number) [generalized from (Pairof Number (Listof Number))]
'(0.3 0.2 0.5)
> (sum '(0.3 0.2 0.5))
- : Real
1.0
> (sum (map (λ: ([x : (Pairof Symbol Number)]) (cdr x)) (list (cons (quote a) 0.3) (cons  (quote b) 0.2) (cons (quote c) 0.5))))
. Type Checker: Polymorphic function map could not be applied to arguments:
Types: (a -> c) (Pairof a (Listof a)) -> (Pairof c (Listof c))
   (a b ... b -> c) (Listof a) (Listof b) ... b -> (Listof c)
Arguments: ((Pairof Symbol Number) -> Number : ((! False @ (cdr) 0) | (False @ (cdr) 0)) (cdr 0)) (List (Pairof 'a Positive-Flonum) (Pairof 'b Positive-Flonum) (Pairof 'c Positive-Flonum))
Expected result: (Listof Real)
 in: (map (λ: ((x : (Pairof Symbol Number))) (cdr x)) (list (cons (quote a) 0.3) (cons (quote b) 0.2) (cons (quote c) 0.5)))

为什么第一个和第二个表达式> (map ...> sum ...按预期工作,但尝试将它们组合会引发类型错误?

> sum
- : ((Listof Real) -> Real)
#<procedure:sum>

我不太明白为什么map根据我的想法(Listof Number) [generalized from (Pairof Number (Listof Number))]返回(Listof Number)而不只是map

2 个答案:

答案 0 :(得分:3)

问题是以下之一:

  1. 您要将参数x声明为Number
  2. 您声明sumReal s
  3. 合作

    在(Typed)球拍文档的某处,解释了类型树。您的代码存在的问题是RealNumber的子类型。因此,当map生成Number的列表时,sum函数将只接受更具体的类型(谢天谢地)会产生错误。

    你可以通过让sum处理任何类型的Numbers(假设你正在使用+应该是安全的)来解决它,或者你明确地声明xReal }(这可能并不总是正确的,但在这个有限的例子中工作正常)。

答案 1 :(得分:0)

问题似乎是sum期望(Listof Real)map正在返回(Listof Number)。解决方案是使用(apply + (map ...))代替(sum (map ...))