Open
Description
In a struct type that implements both gen:sequence
as well as gen:functor
, calling map
uses the sequence implementation rather than the functor one. As far as I can tell, this means that implementing gen:functor
would always have no effect in the cases where these two interfaces overlap. Yet, if a user were content with the lazy map
behavior with gen:sequence
there would be no reason to implement gen:functor
in the first place. On the other hand, if they wanted the sequence mapping behavior with map
they could delegate to it in their implementation of gen:functor
.
Example:
#lang racket
(require data/collection
data/functor
racket/generic
(only-in racket/base (map b:map) (filter b:filter)))
;; implementing only gen:functor
(struct bag (items)
#:transparent
#:methods gen:functor
[(define (map f x)
;; exclude numbers too big to fit in the bag
(bag (b:filter (lambda (v)
(< v 10))
(b:map f (bag-items x)))))])
;; implementing both
(struct bagg (items)
#:transparent
#:methods gen:functor
[(define (map f x)
;; exclude numbers too big to fit in the bag
(bagg (b:filter (lambda (v)
(< v 10))
(b:map f (bagg-items x)))))]
#:methods gen:sequence
[(define/generic -empty? empty?)
(define/generic -first first)
(define/generic -rest rest)
(define (empty? x)
(-empty? (bagg-items x)))
(define (first x)
(-first (bagg-items x)))
(define (rest x)
(-rest (bagg-items x)))])
(map add1 (bag (list 7 8 9)))
(map add1 (bagg (list 7 8 9)))
=>
(bag '(8 9))
#<stream> ['(8 9 10)]
Metadata
Metadata
Assignees
Labels
No labels