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))