not-my-type

Some useful types

Usage no npm install needed!

<script type="module">
  import notMyType from 'https://cdn.skypack.dev/not-my-type';
</script>

README

Not My Type

Build Status
NPM

Some useful types for JavaScript. Emphasizes practicality rather than safety.

Available Types

  • Maybe a
  • Either a b
  • Tuple a b

Maybe a

Represents the absence or presence of a value.

Constructors

Maybe.of : a -> Maybe a

Returns a new Just which represents an existent value.

Maybe.of(42).equals(Just(42)) // true
Just : a -> Maybe a

Returns a new Just which represents an existent value.

Just(42).isJust // true
Nothing : () -> Maybe a

Returns a new Nothing which represents the absence of a value.

Nothing().isJust // false
Maybe.fromUndefinable : * -> Maybe a

Returns Nothing if given undefined, otherwise a new Just wrapping the given value.

Maybe.fromUndefinable(42) // Just(42)

Maybe.fromUndefinable(false) // Just(false)

Maybe.fromUndefinable(undefined) // Nothing

Static Functions

Maybe.flatten : [Maybe a] -> Maybe [a]

Transforms a list of Maybe values into Maybe a list of values. If any Nothing values are found, returns Nothing.

Maybe.flatten([]) // Just([])

Maybe.flatten([Just(1), Just(2), Just(3)]) // Just([1, 2, 3])

Maybe.flatten([Just(1), Nothing(), Just(2)]) // Nothing()

Instance Functions/Values

map : Maybe a -> (a -> b) -> Maybe b

Returns a new Maybe with its inner value modified, if it has one.

Just(42).map(a => a + 1) // Just(43)

Nothing().map(a => a + 1) // Nothing
chain : Maybe a -> (a -> Maybe b) -> Maybe b

Applies a modification to the inner value, if it has one.

function add5IfGreaterThan0(v) {
  return v > 0 ? Just(v + 5) : Nothing();
}

Just(42).chain(add5IfGreaterThan0) // Just(47)

Nothing().map(add5IfGreaterThan0) // Nothing
ap : Maybe (a -> b) -> Maybe a -> Maybe b

Applies a wrapped function to a wrapped argument, if it has both.

Just(a => a + 5).ap(Just(42)) // Just(47)

Nothing().ap(Just(42)) // Nothing
equals : Maybe a -> * -> bool

Checks whether the Maybe is equal to something else. Dispatches equal if the passed argument has one.

Just(42).equals(Just(42)) // true

Nothing().equals(Just('something')) // false
withDefault : Maybe a -> a -> a

Unwraps the inner value, if it has one. If it is Nothing, return the given default.

Just(42).withDefault(35) // 42

Nothing().withDefault('some default') // 'some default'
maybe : Maybe a -> b -> (a -> b) -> a

Like withDefault except it applies a function to the unwrapped value.

Just(42).maybe(35, a => a + 1) // 43

Nothing().maybe('some default', a => `some value ${a}`) // 'some default'
fromJust : Maybe a -> a (UNSAFE)

Unwraps a Just, will throw an error of it's called on Nothing

Just(42).fromJust() // 42

Nothing().fromJust() // throws Error('fromJust called on Nothing')
toMaybe : Maybe a -> Maybe a

No-op.

Just(42).toMaybe() // Just(42)

Nothing().toMaybe() // Nothing
toEither : Maybe a -> b -> Either b a

Just results in a Right of the same value. Nothing yields a Left of the passed value.

Just(42).toEither('val') // Right(42)

Nothing().toEither('val') // Left('val')
isJust : bool

true if on a Just, false if Nothing.

Just(42).isJust // true

Nothing().isJust // false
isNothing : bool

true if on a Nothing, false if Just.

Just(42).isNothing // false

Nothing().isNothing // true

Either a b

Represents one of two potential types of values. Generally, the left value a is an error and b is the result of a successful computation.

Constructors

Either.of : a -> Either ? a

Returns a new Right which generally represents a success value.

Either.of(42).equals(Right(42)) // true
Right : a -> Either ? a

Returns a new Right which generally represents a success value.

Right(42).isRight // true
Left : a -> Either a ?

Returns a new Left which generally represents a failure or error value.

Left('hmmmm').isLeft // true

Static Functions

Either.flatten : [Either a b] -> Either a [b]

Transforms a list of Either values into Either a list of values. If any Left values are found, returns Left of the first one.

Either.flatten([]) // Right([])

Either.flatten([Right(1), Right(2), Right(3)]) // Right([1, 2, 3])

Either.flatten([Right(1), Left('first'), Right(2), Left('snd')]) // Left('first')

Instance Functions/Values

map : Either a b -> (b -> c) -> Either a c

Returns a new Either with its Right value modified. Keeps Left unchanged.

Right(42).map(a => a + 1) // Right(43)

Left('error text').map(a => a + 1) // Left('error text')
bimap : Either a b -> (a -> c) -> (b -> d) -> Either c d

Returns a new Either with the left function applied, given a Left, or the Right function applied, given a Right.

Right(42).bimap(a => a + 1, a => a + 2) // Right(44)

Left(42).bimap(a => a + 1, a => a + 2) // Right(43)
chain : Either a b -> (b -> Either a c) -> Either a c

Applies a modification to the Right value. Keeps Left unchanged.

function add5IfGreaterThan0(v) {
  return v > 0 ? Just(v + 5) : Left('I should be ignored')
}

Right(42).chain(add5IfGreaterThan0) // Right(47)

Left('err text').map(add5IfGreaterThan0) // Left('err text')
ap : Either a (b -> c) -> Either a b -> Either a c

Applies a wrapped function to a wrapped argument, if both are Right.

Right(a => a + 5).ap(Right(42)) // Right(47)

Left('hmmm').ap(Right(42)) // Left('hmmm')
equals : Either a b -> * -> bool

Checks whether the Either is equal to something else. Dispatches equal if the passed argument has one.

Right(42).equals(Right(42)) // true

Left('err').equals(Left('other err')) // false
withDefault : Either a b -> b -> b

Unwraps the Right value, if it has one. If it is Left, return the given default.

Right(42).withDefault(35) // 42

Left('foo').withDefault('some default') // 'some default'
either : Either a b -> (a -> c) -> (b -> c) -> c

Like withDefault except it applies a function to the unwrapped value. The left function is applied if the value is a Left, likewise, right to Right.

Right(42).either(a => a * 2423, a => a + 1) // 43

Left(72).either(a => a - 30, a => a + 1) // 42
fromRight : Either a b -> b (UNSAFE)

Unwraps a Right, will throw an error of it's called on Left

Right(42).fromRight() // 42

Left().fromRight() // throws Error('fromRight called on a Left')
fromLeft : Either a b -> a (UNSAFE)

Unwraps a Left, will throw an error of it's called on Right

Right().fromLeft() // throws Error('fromLeft called on a Right')

Left(42).fromLeft() // 42
toMaybe : Either a b -> Maybe b

Converts Left to Nothing, Right(a) to Just(a).

Right(42).toMaybe() // Just(42)

Left(99).toMaybe() // Nothing
toEither : Either a b -> Either a b

No-op.

Right(42).toEither() // Right(42)

Left(99).toEither() // Left(99)
isRight : bool

true if on a Right, false if Left.

Right(42).isRight // true

Left(99).isRight // false
isLeft : bool

true if on a Left, false if Right.

Right(42).isLeft // false

Left(99).isLeft // true

Tuple a b

Wraps a pair of values.

Constructors

Tuple : a -> b -> Tuple a b

Returns a new Tuple.

Tuple(1, 2).equals(Tuple(1, 1 + 1)) // true

Tuple(1)(2).equals(Tuple(1, 2)) // true

Instance Functions/Values

map : Tuple a b -> (b -> c) -> Tuple a c

Returns a new Tuple with its second, inner value modified.

Tuple(12, 42).map(a => a + 1) // Tuple(12, 43)
bimap : Tuple a b -> (a -> c) -> (b -> d) -> Tuple c d

Returns a new Tuple with the first function applied to the first value, and the second applied to the second

Tuple(99, 'foo').bimap(a => a + 1, b => b + 'bar') // Tuple(100, 'foobar')
fst : a

Is the first value in a Tuple.

Tuple(42, 99).fst // 42
snd : b

Is the second value in a Tuple.

Tuple(42, 99).snd // 99