Skip to content

🌈 Fantasy Land -compliant Either type

License

Notifications You must be signed in to change notification settings

sanctuary-js/sanctuary-either

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fantasy Land

sanctuary-either

The Either type represents values with two possibilities: a value of type Either a b is either a Left whose value is of type a or a Right whose value is of type b.

Either a b satisfies the following Fantasy Land specifications:

> const Useless = require ('sanctuary-useless')

> const isTypeClass = x =>
.   type (x) === 'sanctuary-type-classes/TypeClass@1'

> S.map (k => k + ' '.repeat (16 - k.length) +
.             (Z[k].test (Right (Useless)) ? '\u2705   ' :
.              Z[k].test (Right (['foo'])) ? '\u2705 * ' :
.              /* otherwise */               '\u274C   '))
.       (S.keys (S.unchecked.filter (isTypeClass) (Z)))
[ 'Setoid          ✅ * ',  // if ‘a’ and ‘b’ satisfy Setoid
. 'Ord             ✅ * ',  // if ‘a’ and ‘b’ satisfy Ord
. 'Semigroupoid    ❌   ',
. 'Category        ❌   ',
. 'Semigroup       ✅ * ',  // if ‘a’ and ‘b’ satisfy Semigroup
. 'Monoid          ❌   ',
. 'Group           ❌   ',
. 'Filterable      ❌   ',
. 'Functor         ✅   ',
. 'Bifunctor       ✅   ',
. 'Profunctor      ❌   ',
. 'Apply           ✅   ',
. 'Applicative     ✅   ',
. 'Chain           ✅   ',
. 'ChainRec        ✅   ',
. 'Monad           ✅   ',
. 'Alt             ✅   ',
. 'Plus            ❌   ',
. 'Alternative     ❌   ',
. 'Foldable        ✅   ',
. 'Traversable     ✅   ',
. 'Extend          ✅   ',
. 'Comonad         ❌   ',
. 'Contravariant   ❌   ' ]

Either type representative.

Constructs a value of type Either a b from a value of type a.

> Left ('sqrt undefined for -1')
Left ('sqrt undefined for -1')

Constructs a value of type Either a b from a value of type b.

> Right (42)
Right (42)
  • of (Either) (x) is equivalent to Right (x)
> S.of (Either) (42)
Right (42)
> Z.chainRec (
.   Either,
.   (next, done, x) =>
.     x <= 1 ? Left ('!!') : Right (x >= 1000 ? done (x) : next (x * x)),
.   1
. )
Left ('!!')

> Z.chainRec (
.   Either,
.   (next, done, x) =>
.     x <= 1 ? Left ('!!') : Right (x >= 1000 ? done (x) : next (x * x)),
.   2
. )
Right (65536)
  • show (Left (x)) is equivalent to 'Left (' + show (x) + ')'
  • show (Right (x)) is equivalent to 'Right (' + show (x) + ')'
> show (Left ('sqrt undefined for -1'))
'Left ("sqrt undefined for -1")'

> show (Right ([1, 2, 3]))
'Right ([1, 2, 3])'
  • Left (x) is equal to Left (y) iff x is equal to y according to Z.equals
  • Right (x) is equal to Right (y) iff x is equal to y according to Z.equals
  • Left (x) is never equal to Right (y)
> S.equals (Left ([1, 2, 3])) (Left ([1, 2, 3]))
true

> S.equals (Right ([1, 2, 3])) (Right ([1, 2, 3]))
true

> S.equals (Left ([1, 2, 3])) (Right ([1, 2, 3]))
false
  • Left (x) is less than or equal to Left (y) iff x is less than or equal to y according to Z.lte
  • Right (x) is less than or equal to Right (y) iff x is less than or equal to y according to Z.lte
  • Left (x) is always less than Right (y)
> S.filter (S.lte (Left (1))) ([Left (0), Left (1), Left (2)])
[Left (0), Left (1)]

> S.filter (S.lte (Right (1))) ([Right (0), Right (1), Right (2)])
[Right (0), Right (1)]

> S.filter (S.lte (Left (1))) ([Right (0), Right (1), Right (2)])
[]

> S.filter (S.lte (Right (1))) ([Left (0), Left (1), Left (2)])
[Left (0), Left (1), Left (2)]
  • concat (Left (x)) (Left (y)) is equivalent to Left (concat (x) (y))
  • concat (Right (x)) (Right (y)) is equivalent to Right (concat (x) (y))
  • concat (Left (x)) (Right (y)) is equivalent to Right (y)
  • concat (Right (x)) (Left (y)) is equivalent to Right (x)
> S.concat (Left ('abc')) (Left ('def'))
Left ('abcdef')

> S.concat (Right ([1, 2, 3])) (Right ([4, 5, 6]))
Right ([1, 2, 3, 4, 5, 6])

> S.concat (Left ('abc')) (Right ([1, 2, 3]))
Right ([1, 2, 3])

> S.concat (Right ([1, 2, 3])) (Left ('abc'))
Right ([1, 2, 3])
  • map (f) (Left (x)) is equivalent to Left (x)
  • map (f) (Right (x)) is equivalent to Right (f (x))
> S.map (S.add (1)) (Left ('sqrt undefined for -1'))
Left ('sqrt undefined for -1')

> S.map (S.add (1)) (Right (99))
Right (100)
  • bimap (f) (g) (Left (x)) is equivalent to Left (f (x))
  • bimap (f) (g) (Right (x)) is equivalent to Right (g (x))
> S.bimap (S.toUpper) (S.add (1)) (Left ('abc'))
Left ('ABC')

> S.bimap (S.toUpper) (S.add (1)) (Right (99))
Right (100)
  • ap (Left (x)) (Left (y)) is equivalent to Left (x)
  • ap (Left (x)) (Right (y)) is equivalent to Left (x)
  • ap (Right (f)) (Left (x)) is equivalent to Left (x)
  • ap (Right (f)) (Right (x)) is equivalent to Right (f (x))
> S.ap (Left ('div undefined for 0')) (Left ('sqrt undefined for -1'))
Left ('div undefined for 0')

> S.ap (Left ('div undefined for 0')) (Right (99))
Left ('div undefined for 0')

> S.ap (Right (S.add (1))) (Left ('sqrt undefined for -1'))
Left ('sqrt undefined for -1')

> S.ap (Right (S.add (1))) (Right (99))
Right (100)
  • chain (f) (Left (x)) is equivalent to Left (x)
  • chain (f) (Right (x)) is equivalent to f (x)
> const sqrt = n => n < 0 ? Left ('sqrt undefined for ' + show (n))
.                         : Right (Math.sqrt (n))

> S.chain (sqrt) (Left ('div undefined for 0'))
Left ('div undefined for 0')

> S.chain (sqrt) (Right (-1))
Left ('sqrt undefined for -1')

> S.chain (sqrt) (Right (25))
Right (5)
  • alt (Left (y)) (Left (x)) is equivalent to Left (y)
  • alt (Right (y)) (Left (x)) is equivalent to Right (y)
  • alt (Left (y)) (Right (x)) is equivalent to Right (x)
  • alt (Right (y)) (Right (x)) is equivalent to Right (x)
> S.alt (Left ('B')) (Left ('A'))
Left ('B')

> S.alt (Right (1)) (Left ('C'))
Right (1)

> S.alt (Left ('D')) (Right (2))
Right (2)

> S.alt (Right (4)) (Right (3))
Right (3)
  • reduce (f) (x) (Left (y)) is equivalent to x
  • reduce (f) (x) (Right (y)) is equivalent to f (x) (y)
> S.reduce (S.concat) ([1]) (Left ('sqrt undefined for -1'))
[1]

> S.reduce (S.concat) ([1]) (Right ([2]))
[1, 2]
  • traverse (A) (f) (Left (x)) is equivalent to of (A) (Left (x))
  • traverse (A) (f) (Right (x)) is equivalent to map (Right) (f (x))
> S.traverse (Array) (S.words) (Left ('sqrt undefined for -1'))
[Left ('sqrt undefined for -1')]

> S.traverse (Array) (S.words) (Right ('foo bar baz'))
[Right ('foo'), Right ('bar'), Right ('baz')]
  • extend (f) (Left (x)) is equivalent to Left (x)
  • extend (f) (Right (x)) is equivalent to Right (f (Right (x)))
> S.extend (S.reduce (S.add) (1)) (Left ('sqrt undefined for -1'))
Left ('sqrt undefined for -1')

> S.extend (S.reduce (S.add) (1)) (Right (99))
Right (100)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy