#lang scheme (require (prefix-in base: (only-in scheme + /))) (require "typeclass-units.ss") ;; A class of things for which addition is defined. (define-signature addable^ (zero +)) ;; A class of things for which division is defined. (define-signature divisible^ (/)) ;; Standard arithmetic on numbers. (define-instance (addable^ divisible^) num@ (define zero 0) (define + base:+) (define / base:/)) ;; Addition over strings is defined as string-append. (define-instance addable^ string@ (define zero "") (define + string-append)) ;; The "+" function is a generic addition operation. (define-constrained (+ (addable^) => x y) (+ x y)) ((+ num@) 3 4) ; Adding numbers ((+ string@) "hi " "there") ; Adding strings ;; A helper combinator. (define (flip f) (λ(x y) (f y x))) ;; The definition of the "mean" function requires both addition and division. (define-constrained (mean (addable^ divisible^) => items) (/ (foldl (flip +) zero items) (length items))) ;; Computing the mean of a list of numbers. ((mean num@ num@) '(4 5 6)) ;; Try giving an incompatible instance of divisible^... doesn't work. ((mean string@ num@) '("what " "is " "an average " "string?"))