Functional programming 键入的球拍将任意球拍转换为全部球拍(a)
我正在尝试调用Functional programming 键入的球拍将任意球拍转换为全部球拍(a),functional-programming,scheme,racket,typed-racket,typed,Functional Programming,Scheme,Racket,Typed Racket,Typed,我正在尝试调用take对flatten的输出。问题是take需要一个a列表,但是flatten返回一个Any列表。有办法在他们之间转换吗?或者我应该采取的其他方法?我在Racket文档中找不到任何例子 (: extend (All (a) (-> (Listof a) Integer (Listof a)))) (define (extend l n) ; extend a list to
take
对flatten
的输出。问题是take
需要一个a
列表,但是flatten
返回一个Any
列表。有办法在他们之间转换吗?或者我应该采取的其他方法?我在Racket文档中找不到任何例子
(: 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>
@亚历克西斯·金是对的。
flatte
函数具有更复杂的行为,不适合您需要的类型。append*
函数更简单,在这里它实际上是您所需要的,而不是flatten
(: 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))
在您使用它的地方:
; n : Integer
; l : (Listof a)
(take (flatten (make-list n l)) n)
; expected type: (Listof a)
展平的输入是(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*>
这里的问题是,flatte
确实很难给出精确的类型,因为它可以展平任意深度的列表。请考虑使用<代码>附录*>代码>它做的事情更简单,因此有更好的类型。
(: 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))