README.md 2.3 KB

Trait

A trait/typeclass system for Chicken Scheme, inspired by Type Classes Without Types. But currently my implementation is in a very early stage, so it's much more simpler and inferior than the one described in the paper.

I prefer the name typeclass, but there has been an egg named typeclass already. So I borrowed the word trait from Rust.

Example

Eq

(import trait)

(define-record point x y)

(define-trait Eq
  (==)
  (/= (lambda (a b) (not (== a b)))))

(define-trait-impl (Eq number?)
  (== =))

(define-trait-impl (Eq symbol?)
  (== eq?))

(define-trait-impl (Eq list?)
  (== equal?))

(define-trait-impl (Eq point?)
  (== (lambda (a b) (and (point? b)
                         (= (point-x a) (point-x b))
                         (= (point-y a) (point-y b))))))

(display (list (== 'a 'a)
               (/= 'a 'a)

               (== 1 1)
               (/= 1 1)

               (== 1 2)
               (/= 1 2)

               (== (list 1 2) (list 1 2))
               (/= (list 1 2) (list 1 2))

               (== (make-point 3 4) (make-point 3 4))
               (/= (make-point 3 4) (make-point 3 4))))

Monad

(import trait)

(define-trait Monad
  (>>=)
  (return))

(define-record nullable is-null value)
(define (make-some value)
  (make-nullable #f value))
(define (make-null)
  (make-nullable #t '()))
(define (nullable-type x)
  (if (nullable-is-null x)
      'null
      'some))

(define-trait-impl (Monad nullable?)
  (>>= (lambda (m f)
         (let ((type (nullable-type m)))
           (cond ((eq? type 'null)
                  (make-null))
                 ((eq? type 'some)
                  (f (nullable-value m)))))))
  (return make-some))

(define (*2 a)
  (make-some (* 2 a)))

(display (nullable-value (>>= (make-some 3) *2)))
(newline)

(display ((with-type nullable? return) 42))
(newline)

(define x (make-some 42))
(let ((return (with-type-of x Monad return)))
  (display (nullable-value (return 99))))