Typed Racket 将 Any 转换为 All (a)
Typed Racket convert Any to All (a)
我正尝试在 flatten
的输出上调用 take
。问题是 take
需要 a
的列表,但 flatten
returns 需要 Any
的列表。有没有办法在它们之间进行转换?或者我应该采取的其他方法?我无法在球拍文档中找到任何示例。
(: extend (All (a) (-> (Listof a) Integer (Listof a))))
(define (extend l n)
; extend a list to length 'n' by appending it to itself
;
; @l list of any
; @n int
; @return list of any
(take (flatten (make-list n l)) n))
来自解释器,这里是每个函数的确切类型以供参考。
> take
- : (All (a) (-> (Listof a) Integer (Listof a)))
#<procedure:take>
> flatten
- : (-> Any (Listof Any))
#<procedure:flatten>
这里也是错误提示,供参考。
alg/waterfall.rkt:65:2: Type Checker: Polymorphic function `take' could not be applied to arguments:
Argument 1:
Expected: (Listof a)
Given: (Listof Any)
Argument 2:
Expected: Integer
Given: Integer
Result type: (Listof a)
Expected result: (Listof a)
@Alexis King 是对的。 flatten
函数具有更复杂的行为,不适合您需要的类型。 append*
函数更简单,这里其实就是你需要的,而不是flatten
.
在你使用的地方:
; n : Integer
; l : (Listof a)
(take (flatten (make-list n l)) n)
; expected type: (Listof a)
flatten
的输入是 (Listof (Listof a))
,要进行类型检查,输出必须是 (Listof a)
。这必须是真实的 *即使 a
包含列表*.
你想要的函数是 (Listof (Listof a)) -> (Listof a)
类型的东西。现在,flatten
总是有那个类型吗?不,它不能,这是一个反例:
a = (Listof Integer)
input : (Listof (Listof (Listof Integer)))
input = (list (list (list 1)))
expected output type: (Listof (Listof Integer))
actual output value: (list 1)
因此 flatten
不能有类型 (Listof (Listof a)) -> (Listof a)
。你需要的是append*
,它确实有那个类型。
> append*
- : (All (a) (-> (Listof (Listof a)) (Listof a)))
#<procedure:append*>
在您的示例中,您可以在使用 flatten
的地方使用 append*
。
(: extend (All (a) (-> (Listof a) Integer (Listof a))))
(define (extend l n)
; extend a list to length 'n' by appending it to itself
;
; @l list of any
; @n int
; @return list of any
(take (append* (make-list n l)) n))
我正尝试在 flatten
的输出上调用 take
。问题是 take
需要 a
的列表,但 flatten
returns 需要 Any
的列表。有没有办法在它们之间进行转换?或者我应该采取的其他方法?我无法在球拍文档中找到任何示例。
(: extend (All (a) (-> (Listof a) Integer (Listof a))))
(define (extend l n)
; extend a list to length 'n' by appending it to itself
;
; @l list of any
; @n int
; @return list of any
(take (flatten (make-list n l)) n))
来自解释器,这里是每个函数的确切类型以供参考。
> take
- : (All (a) (-> (Listof a) Integer (Listof a)))
#<procedure:take>
> flatten
- : (-> Any (Listof Any))
#<procedure:flatten>
这里也是错误提示,供参考。
alg/waterfall.rkt:65:2: Type Checker: Polymorphic function `take' could not be applied to arguments:
Argument 1:
Expected: (Listof a)
Given: (Listof Any)
Argument 2:
Expected: Integer
Given: Integer
Result type: (Listof a)
Expected result: (Listof a)
@Alexis King 是对的。 flatten
函数具有更复杂的行为,不适合您需要的类型。 append*
函数更简单,这里其实就是你需要的,而不是flatten
.
在你使用的地方:
; n : Integer
; l : (Listof a)
(take (flatten (make-list n l)) n)
; expected type: (Listof a)
flatten
的输入是 (Listof (Listof a))
,要进行类型检查,输出必须是 (Listof a)
。这必须是真实的 *即使 a
包含列表*.
你想要的函数是 (Listof (Listof a)) -> (Listof a)
类型的东西。现在,flatten
总是有那个类型吗?不,它不能,这是一个反例:
a = (Listof Integer)
input : (Listof (Listof (Listof Integer)))
input = (list (list (list 1)))
expected output type: (Listof (Listof Integer))
actual output value: (list 1)
因此 flatten
不能有类型 (Listof (Listof a)) -> (Listof a)
。你需要的是append*
,它确实有那个类型。
> append*
- : (All (a) (-> (Listof (Listof a)) (Listof a)))
#<procedure:append*>
在您的示例中,您可以在使用 flatten
的地方使用 append*
。
(: extend (All (a) (-> (Listof a) Integer (Listof a))))
(define (extend l n)
; extend a list to length 'n' by appending it to itself
;
; @l list of any
; @n int
; @return list of any
(take (append* (make-list n l)) n))