2017-07-01 6 views
1

任意の数のリストを一緒にジップする関数の構文に苦しんでいます。私は現在持っている:評価を次のエラーが発生残りの引数を持つ型付きラケットのZip関数

(define (zip . [lsts : (Listof Any) *]) (apply map (inst list Any) lsts))

:これら以来

Error: struct:exn:fail:syntax /Applications/Racket v6.6/collects/racket/private/kw.rkt:929:25: Type Checker: Bad arguments to function in `apply':

Domains: (-> a b ... b c) (Listof a) (Listof b) ... b

(-> a c) (Pairof a (Listof a))

Arguments: (-> Any * (Listof Any)) (Listof (Listof Any)) *

in: (#%app apply map (#%expression list) lsts)

は大丈夫評価:

(apply map (inst list Any) '(("asd" 1 2) ("cat" 3 4))) ;;(("asd" "cat") (1 3) (2 4))

(define (test . [lsts : (Listof Any) *]) lsts) (test '(1 2 3) '(2 3 "dogs")) ;;((1 2 3) (2 3 "dogs"))

私はタイプチェッカーのは、私は次のように評価しようと、同様のエラーを取得するため、引数は、渡されていないときは常に失敗についてapplyを訴えて思う:

(apply map (inst list Any) '()) 

Error: struct:exn:fail:syntax /Applications/Racket v6.6/collects/racket/private/kw.rkt:929:25: Type Checker: Bad arguments to function in `apply':

Domains: (-> a b ... b c) (Listof a) (Listof b) ... b

(-> a c) (Pairof a (Listof a))

Arguments: (-> Any * (Listof Any)) Null *

in: (#%app apply map (#%expression list) (quote()))

しかし、私はに指定するかどうかはわかりません少なくとも1つの引数(リスト)を取るようにする関数。

答えて

2

関数mapは少なくとも1つのリストを引数として取る必要があります。引き数ゼロのzipを呼び出すとどうなるか考えてみましょう。その後、リストがゼロのmapが呼び出されますが、これは許可されていません。だから、あなたのzip関数を制限して、1つ以上の引数を取らなければなりません。

#lang typed/racket 

(define (zip [lst : (Listof Any)] . [lsts : (Listof Any) *]) 
    (apply map (inst list Any) lst lsts)) 

もう1つ:これは多態性の方が良いでしょう。これは、次のように残りの引数の前に引数を指定することで可能になります。

#lang typed/racket 

(: zip : (∀ (A) (-> (Listof A) (Listof A) * (Listof (Listof A))))) 
(define (zip lst . lsts) 
    (apply map (inst list A) lst lsts)) 

ドメインはまだ(Listof A) (Listof A) *だけでなく(Listof A) *にする必要があることに注意してください。

+0

包括的な回答をいただきありがとうございます。私はあなたの答えに似たような行に沿って何かを試していましたが、なんらかの理由で 'lsts'と' lsts'が良いアイデアであると判断し、うまくいかなかったときにあきらめて、 'zipそれは2つの議論しか取らなかった。私は今からこれを使うつもりです。多形性のシグネチャにもよく似ています。 – xdl

関連する問題