Typed Racket convert Any to All(a)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Typed Racket convert Any to All(a)相关的知识,希望对你有一定的参考价值。

我试图在take的输出上调用flatten。问题是take需要一个a列表,但flatten返回Any列表。有没有办法在它们之间进行转换?或者其他一些我应该采取的方法?我无法在Racket Docs中找到任何示例。

(: 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*>

在您的示例中,您可以使用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)) 

以上是关于Typed Racket convert Any to All(a)的主要内容,如果未能解决你的问题,请参考以下文章

Typed Racket 中的打字功能与 Clojure 中的类类型功能有何异同?

在 Racket 中将 Exact-Rational 转换为 Integer

akka-typed - typed-actor, typed messages

akka-typed - typed-actor, typed messages

如何发出和处理自定义事件?

从 C 调用 Racket 函数