[plt-scheme] Re: polymorphism of primitive types
On Oct 18, 2005, at 3:07 PM, Bill Wood wrote:
> On Tue, 2005-10-18 at 12:26 -0400, David Van Horn wrote:
> . . .
>> At least one of the argument lists must be finite:
>>
>> (map + '(3 1 4 1) (circular-list 1 0)) => (4 1 5 1)
>
> Since you brought it up, I've been wondering if there is some
> compelling
> reason to require the list arguments to HOFs like map, zip, etc. to all
> be of the same length? The Common Lisp versions don't require it.
> There have been occasions when I found the more relaxed versions, such
> as SRFI 1 and Common Lisp's, to be *very* useful. The relaxed versions
> also help make circular lists more useful.
>
> I asked this question (in a very relaxed fashion) on the OCaml list and
> received thundering silence for my insolence :-)
An interesting question comes up here: what is the contract for such a
function?
Here is my partial attempt:
(module mymap mzscheme
(require (lib "contract.ss")
(lib "list.ss"))
(define (mymap f . argl)
(let loop ([argl argl])
(cond
[(ormap null? argl) '()]
[(andmap pair? argl) (cons (apply f (map car argl)) (loop (map
cdr argl)))]
[else (error 'mymap "can't happen: out of cons cells and no
empty list")])))
;; (Listof X) Nat -> Boolean
(define (has-at-least-as-many-cons-as l min)
(let loop ([l l][min min])
(cond [(null? l) #t]
[else (and (pair? l) (loop (cdr l) (- min 1)))])))
;; (Listof X) -> Boolean
(define (pre-mymap argl)
(define proper-lists (filter list? argl))
(and (pair? proper-lists)
(andmap (let ([length-of-shortest-proper-list (apply min (map
length proper-lists))])
(lambda (l) (has-at-least-as-many-cons-as l
length-of-shortest-proper-list)))
argl)))
(define pre-mymap-string
"all args have as many leading cons cells as the shortest proper
list")
(provide/contract
[mymap {(procedure?)
(flat-named-contract pre-mymap-string pre-mymap)
;; MF to Robby: this doesn't check whether the procedure?
has the
;; proper arity. I don't know how to formulate such a
contract.
. ->* .
(list?)}]))
Now you can use it as advertised and it is contracted.
But it would blow up on this:
(let/ec jump
(mymap (lambda (x y) (if (= x y) (jump #f) (+ x y))) '(1 2
. 3) '(1 . 2)))
Should it? -- Matthias