2017-12-20 17 views
2

takeflattenの出力に呼び出そうとしています。問題は、takeaのリストを必要としますが、flattenAnyのリストを返します。それらの間で変換する方法はありますか?あるいは私が取るべき別のアプローチ?私はRacket Docsで例を見つけることができませんでした。型付きラケットすべてに変換するすべて(a)

(: 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) 
+2

ここで問題となるのは、「平坦化」は、任意の深さのリストを平坦化するため、正確な型を指定することは実際には困難です。代わりにここで 'append *'の使用を検討してください。それはより簡単なことであり、したがってより良いタイプを持っています。 –

答えて

1

@アレクシス・キングが正しい。 flatten関数は、必要な型に適合しないより複雑な動作をします。 append*関数はより簡単で、ここでは実際にはflattenの代わりに必要なものです。あなたはそれを使用する代わりに

flatten

; n : Integer 
; l : (Listof a) 
(take (flatten (make-list n l)) n) 
; expected type: (Listof a) 

入力は(Listof (Listof a))であり、それはです。TypeCheckするための出力は(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)) 
関連する問題