Skip to content

Cannot define the writer monad #93

@Tuplanolla

Description

@Tuplanolla

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

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