Skip to content

Bug: functor map should have priority over sequence map #11

Open
@countvajhula

Description

@countvajhula

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

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions