strengthen typing on `shift`

pull/3/head
Matthew Butterick 9 years ago
parent 124b0f5597
commit 3d6b75699a

@ -166,25 +166,25 @@
(define/typed+provide shift (define/typed+provide shift
(case-> ((Listof Any) (U Integer (Listof Integer)) -> (Listof Any)) (All (A) (case-> ((Listof (Option A)) (U Integer (Listof Integer)) -> (U (Listof (Option A)) (Listof (Listof (Option A)))))
((Listof Any) (U Integer (Listof Integer)) Any -> (Listof Any)) ((Listof (Option A)) (U Integer (Listof Integer)) (Option A) -> (U (Listof (Option A)) (Listof (Listof (Option A)))))
((Listof Any) (U Integer (Listof Integer)) Any Boolean -> (Listof Any))) ((Listof (Option A)) (U Integer (Listof Integer)) (Option A) Boolean -> (U (Listof (Option A)) (Listof (Listof (Option A)))))))
(case-lambda (case-lambda
[(xs shift-amount-or-amounts) [(xs shift-amount-or-amounts)
(shift xs shift-amount-or-amounts #f #f)] (shift xs shift-amount-or-amounts #f #f)]
[(xs shift-amount-or-amounts fill-item) [(xs shift-amount-or-amounts fill-item)
(shift xs shift-amount-or-amounts fill-item #f)] (shift xs shift-amount-or-amounts fill-item #f)]
[(xs shift-amount-or-amounts fill-item cycle) [(xs shift-amount-or-amounts fill-item cycle)
(define/typed (do-shift xs how-far) (define/typed (do-shift xs fill-item how-far)
((Listof Any) Integer -> (Listof Any)) (All (A2) ((Listof (Option A2)) (Option A2) Integer -> (Listof (Option A2))))
(define abs-how-far (abs how-far)) (define abs-how-far (abs how-far))
(cond (cond
[(> abs-how-far (length xs)) (error 'shift "index is too large for list\nindex: ~a\nlist: ~v" how-far xs)] [(> abs-how-far (length xs)) (error 'shift "index is too large for list\nindex: ~a\nlist: ~v" how-far xs)]
[(= how-far 0) xs] [(= how-far 0) xs]
[(positive? how-far) [(positive? how-far)
(append (make-list abs-how-far fill-item) (drop-right xs abs-how-far))] ((inst append (Option A2)) ((inst make-list (Option A2)) abs-how-far fill-item) (drop-right xs abs-how-far))]
;; otherwise how-far is negative ;; otherwise how-far is negative
[else (append (drop xs abs-how-far) (make-list abs-how-far fill-item))])) [else (append (drop xs abs-how-far) (make-list abs-how-far fill-item))]))
(if (list? shift-amount-or-amounts) (if (list? shift-amount-or-amounts)
(map (λ:([amount : Integer]) (do-shift xs amount)) shift-amount-or-amounts) ((inst map (Listof (Option A)) Integer) (λ:([amount : Integer]) (do-shift xs fill-item amount)) shift-amount-or-amounts)
(do-shift xs shift-amount-or-amounts))])) (do-shift xs fill-item shift-amount-or-amounts))]))

Loading…
Cancel
Save