3.3 Instances
On this page:
3.3.1 Box
box-applicative
box-functor
box-monad
3.3.2 Event
event-applicative
event-functor
event-monad
3.3.3 List
list-applicative
list-functor
list-monad
list-monoid
list-semigroup
3.3.4 Maybe
Maybe
Nothing
Just
maybe-applicative
maybe-functor
maybe-monad
3.3.5 Truthy
Truthy
Fail
3.3.6 Values
values-applicative
values-functor
values-monad
7.7

3.3 Instances

3.3.1 Box

 (require algebraic/data/box) package: algebraic

extends box-functor

value

pure : procedure?

value

<*> : procedure?

value

liftA2 : procedure?

Examples:
> (with-instance box-applicative
    (<*> (pure add1) (pure 2)))

'#&3

> (with-instance box-applicative
    (liftA2 + (pure 4) (pure 5)))

'#&9

instance

box-functor

value

fmap : procedure?

Example:
> (with-instance box-functor
    (fmap (>> :: '!)  #&?))

'#&(! . ?)

instance

box-monad

value

>>= : procedure?

Example:
> (with-instance box-monad
    (do (`(? ,x)) <- (box '(? 2))
        (return `(! ,(add1 x)))))

'#&(! 3)

3.3.2 Event

 (require algebraic/data/event) package: algebraic

extends event-monad

value

pure : procedure?

value

liftA2 : procedure?

Examples:
> (with-instance event-applicative (sync (pure 1 2 3)))

1

2

3

> (with-instance event-applicative
    (sync (liftA2 list (pure 1 2) (pure 3 4))))

'(1 2 3 4)

value

fmap : procedure?

Examples:
> (with-instance event-functor
    (sync (fmap (λ _ (id 1 2 3)) always-evt)))

1

2

3

instance

event-monad

value

>>= : procedure?

value

return : procedure?

Examples:
> (with-instance event-monad
    (sync (>>= (return 1 2 3) (.. return +))))

6

3.3.3 List

 (require algebraic/data/list) package: algebraic

extends list-functor

value

pure : procedure?

value

<*> : procedure?

value

liftA2 : procedure?

value

*> : procedure?

Examples:

> (with-instance list-applicative
    (<*> (<*> (pure (>>* ::)) '(1)) '(2)))

'((1 . 2))

> (with-instance list-applicative (liftA2 :: '(?) '(!)))

'((? . !))

> (with-instance list-applicative (*> '(1) '(2)))

'(2)

instance

list-functor

value

fmap : procedure?

Example:
> (with-instance list-functor (fmap add1 '(1 2 3 4)))

'(2 3 4 5)

instance

list-monad

value

>>= : procedure?

value

return : procedure?

value

>>M : procedure?

value

fail : procedure?

Examples:

> (with-instance list-monad (>>M (return 1) (return 2)))

'(2)

> (with-instance list-monad (fail '!?))

'()

> (with-instance list-monad (join '((1) (2))))

'(1 2)

instance

list-monoid

value

mempty : null?

value

mconcat : procedure?

Example:
> (with-instance list-monoid (mconcat '(1 2) '(3 4) mempty))

'(1 2 3 4)

value

<> : procedure?

value

stimes : procedure?

Examples:
> (with-instance list-semigroup (<> '(1 2) '(3 4)))

'(1 2 3 4)

> (with-instance list-semigroup (stimes 3 '(! ?)))

'(! ? ! ? ! ?)

3.3.4 Maybe

 (require algebraic/data/maybe) package: algebraic

The Maybe sum, and associated operations.

sum

Maybe

The Maybe sum encapsulates an optional value. A member of Maybe either contains a value a (represented as (Just a)), or it is empty (represented as Nothing). Using Maybe is a good way to deal with errors or exceptional cases without resorting to drastic measures such as error.

The Maybe sum is also a monad. It is a simple kind of error monad, where all errors are represented by Nothing. A richer error monad can be built using the Either type.

product

Nothing

product

Just

value

pure : procedure?

value

<*> : procedure?

value

liftA2 : procedure?

value

*> : procedure?

Examples:

> (with-instance maybe-applicative (<*> (pure add1) (pure 2)))

(Just 3)

> (with-instance maybe-applicative (<*> (pure add1) Nothing))

Nothing

> (with-instance maybe-applicative (<*> Nothing (pure 2)))

Nothing

> (with-instance maybe-applicative (liftA2 + (pure 1) (pure 2)))

(Just 3)

> (with-instance maybe-applicative (liftA2 + Nothing (pure 2)))

Nothing

> (with-instance maybe-applicative (liftA2 + (pure 1) Nothing))

Nothing

> (with-instance maybe-applicative (*> (pure 1) (pure 2)))

(Just 2)

> (with-instance maybe-applicative (*> Nothing (pure 2)))

Nothing

> (with-instance maybe-applicative (*> (pure 1) Nothing))

Nothing

value

fmap : procedure?

Examples:
> (with-instance maybe-functor (fmap add1 (Just 2)))

(Just 3)

> (with-instance maybe-functor (fmap add1 Nothing))

Nothing

instance

maybe-monad

extends MaybeApplicative

value

>>= : procedure?

value

>>M : procedure?

value

fail : procedure?

Examples:
> (with-instance maybe-monad
    (>>= (Just 2) (.. return add1)))

(Just 3)

> (with-instance maybe-monad (>>= Nothing (.. Just add1)))

Nothing

> (with-instance maybe-monad (>>M (Just 1) (Just 2)))

(Just 2)

> (with-instance maybe-monad (>>M Nothing (Just 2)))

Nothing

> (with-instance maybe-monad (fail '!!))

Nothing

3.3.5 Truthy

 (require algebraic/data/truthy) package: algebraic

The Truthy sum, and associated operations.

sum

Truthy

product

Fail

Functions that return #f to indicate failure can be chained together with and and or.

> (define Δ (make-hasheq))
> (or (hash-ref Δ 'A #f)
    (and (hash-set! Δ 'A (random 100))
         (hash-ref  Δ 'A)))

40

> Δ

'#hasheq((A . 40))

But #f does not always indicate failure.

> (hash-set! Δ 'B #f)
> (or (hash-ref Δ 'B #f)
      (and (hash-set! Δ 'B (random 100))
           (hash-ref  Δ 'B)))

28

> Δ

'#hasheq((A . 40) (B . 28))

The Truthy monad uses the Fail product as a failure indicator distinct from #f.

Truthy is like the Maybe sum if Just were implicitly applied to all non-#f values.

> (id (hash-ref Δ 'B (const Fail))
      (hash-ref Δ 'C (const Fail)))

28

Fail

Truthy is a lazy monad. With do~-notation, several Truthy expressions can be evaluated in sequence. If an expression evaluates to Fail, the sequence short circuits.

> (hash-set! Δ 'C #f)
> (with-instance truthy-monad
    ((do~ (λ () ((function [Fail #t] [_ Fail])
                 ((do~ (λ () (hash-ref  Δ 'C (const Fail)))))))
          (do~ (λ () (hash-set! Δ 'C (random 100)))
               (λ () (hash-ref  Δ 'C))))))

Fail

> Δ

'#hasheq((A . 40) (B . 28) (C . #f))

> (with-instance truthy-monad
    ((do~ (λ () ((function [Fail #t] [_ Fail])
                 ((do~ (λ () (hash-ref  Δ 'D (const Fail)))))))
          (do~ (λ () (hash-set! Δ 'D (random 100)))
               (λ () (hash-ref  Δ 'D))))))

27

> Δ

'#hasheq((A . 40) (B . 28) (C . #f) (D . 27))

As a convenience, truthy-and, truthy-not, and truthy-or reduce the boilerplate.

> (with-instance truthy-monad
    (truthy-or (truthy-and (hash-ref  Δ 'C (const Fail)))
               (truthy-and (hash-set! Δ 'C (random 100))
                           (hash-ref  Δ 'C))))

#f

> Δ

'#hasheq((A . 40) (B . 28) (C . #f) (D . 27))

> (with-instance truthy-monad
    (truthy-or (truthy-and (hash-ref  Δ 'D (const Fail)))
               (truthy-and (hash-set! Δ 'D (random 100))
                           (hash-ref  Δ 'D))))

27

> Δ

'#hasheq((A . 40) (B . 28) (C . #f) (D . 27))

3.3.6 Values

 (require algebraic/data/values) package: algebraic

extends ValuesFunctor

value

pure : procedure?

value

liftA2 : procedure?

Examples:

> (with-instance values-applicative
    (liftA2 list
            (λ () (pure 1 2))
            (λ () (pure 3 4))))

'(1 2 3 4)

value

fmap : procedure?

Example:
> (with-instance values-functor (fmap list (λ () (id 1 2 3))))

'(1 2 3)

instance

values-monad

extends ValuesApplicative

value

>>= : procedure?

value

return : procedure?

value

>>M : procedure?

Examples:
> (with-instance values-monad (>>= (λ () (return 1 2 3)) +))

6

> (with-instance values-monad (>>M (λ () 1) (λ () 2)))

2