-
Notifications
You must be signed in to change notification settings - Fork 6
Open
Description
I tried to define the writer monad with an arbitrary monoid as the accumulator,
but could not figure out how to express the necessary class constraint.
The following program raises the error
writer.rkt:46:45: <>: no instance for semigroup
even though it should produce the value
(list (list "first" "third" "second" "fourth") 62).
Is this a limitation of the library or my own mistake?
#lang algebraic/racket/base
(require racket/match)
(require algebraic/control/applicative)
(require algebraic/control/monad)
(require algebraic/data/functor)
(require algebraic/data/list)
(require algebraic/data/monoid)
(require algebraic/data/semigroup)
(define (tell s)
(list s (void)))
(define (listen a)
(match a
((list s x) (list s (list s x)))))
(define (pass p)
(match p
((list s (list f x)) (list (f s) x))))
(define-syntax writer-functor
(instance functor
(fmap (lambda (f a)
(match a
((list s x) (list s (f x))))))))
(define-syntax writer-applicative
(instance applicative
extends (writer-functor)
(pure (lambda (x) (list mempty x)))
(<*> (lambda (p a)
(match p
((list s f) (match a
((list t x) (list (<> s t) (f x))))))))))
(define-syntax writer-monad
(instance monad
extends (writer-applicative)
(>>= (lambda (a k)
(match a
((list s x) (match (k x)
((list t y) (list (<> s t) y)))))))))
(with-instances (list-monoid writer-monad)
(>>= (pure 42) (lambda (x)
(>>M (tell (list "first"))
(>>= (pure 13) (lambda (y)
(>>= (pass (>>M (tell (list "second"))
(>>M (tell (list "third"))
(pure (list reverse 7))))) (lambda (z)
(>>M (tell (list "fourth"))
(pure (+ x y z)))))))))))Metadata
Metadata
Assignees
Labels
No labels