Options
All
  • Public
  • Public/Protected
  • All
Menu

The Apply type class, a weaker version of Applicative, exposing ap (apply), but not pure.

This type class is exposed in addition to Applicative because there are data types for which we can't implement pure, but that could still benefit from an ap definition. For example in case of a Map<K, ?> we couldn't define pure for it because we don't have a K key.

MUST obey the laws defined in ApplyLaws.

Note that having an Apply instance implies that a Functor implementation is also available, which is why Apply is a subtype of Functor.

Implementation notes

Even though in TypeScript the Funfix library is using abstract class to express type classes, when implementing this type class it is recommended that you implement it as a mixin using "implements", instead of extending it directly with "extends". See TypeScript: Mixins for details and note that we already have applyMixins defined.

Implementation example:

import {
  HK, Apply,
  registerTypeClassInstance,
  applyMixins
} from "funfix"

// Type alias defined for readability.
// HK is our encoding for higher-kinded types.
type BoxK<T> = HK<Box<any>, T>

class Box<T> implements HK<Box<any>, T> {
  constructor(public value: T) {}

  // Implements HK<Box<any>, A>, not really needed, but useful in order
  // to avoid type casts. Note these can and should be undefined:
  readonly _funKindF: Box<any>
  readonly _funKindA: T
}

class BoxApply implements Apply<Box<any>> {
  map<A, B>(fa: BoxK<A>, f: (a: A) => B): Box<B> {
    const a = (fa as Box<A>).value
    return new Box(f(a))
  }

  ap<A, B>(fa: BoxK<A>, ff: BoxK<(a: A) => B>): Box<B> {
    const a = (fa as Box<A>).value
    const f = (ff as Box<(a: A) => B>).value
    return new Box(f(a))
  }

  // Mixed-in, as these have default implementations
  map2: <A, B, Z>(fa: BoxK<A>, fb: BoxK<B>, f: (a: A, b: B) => Z) => Box<Z>
  product: <A, B> (fa: BoxK<A>, fb: BoxK<B>) => Box<[A, B]>
}

// Call needed in order to implement `map2` and `product` using
// the default implementations defined by `Apply`, because
// we are using `implements` instead of `extends` above and
// because in this sample we want the default implementations,
// but note that you can always provide your own definitions
applyMixins(BoxApply, [Apply])

// Registering global Apply instance for Box, needed in order
// for the `applyOf(Box)` calls to work
registerTypeClassInstance(Apply)(Box, new BoxApply())

We are using implements in order to support multiple inheritance and to avoid inheriting any static members. In the Flow definitions (e.g. .js.flow files) for Funfix these type classes are defined with "interface", as they are meant to be interfaces that sometimes have default implementations and not classes.

Credits

This type class is inspired by the equivalent in Haskell's standard library and the implementation is inspired by the Typelevel Cats project.

Type parameters

  • F

Hierarchy

  • Apply

Implements

Implemented by

Index

Methods

Methods

ap

  • ap<A, B>(fa: HK<F, A>, ff: HK<F, function>): HK<F, B>
  • Given a value and a function in the Apply context, applies the function to the value.

    Type parameters

    • A

    • B

    Parameters

    • fa: HK<F, A>
    • ff: HK<F, function>

    Returns HK<F, B>

map

  • map<A, B>(fa: HK<F, A>, f: function): HK<F, B>
  • Inherited from Functor.map.

    Type parameters

    • A

    • B

    Parameters

    • fa: HK<F, A>
    • f: function
        • (a: A): B
        • Parameters

          • a: A

          Returns B

    Returns HK<F, B>

map2

  • map2<A, B, Z>(fa: HK<F, A>, fb: HK<F, B>, f: function): HK<F, Z>
  • Applies the pure (binary) function f to the effectful values fa and fb.

    map2 can be seen as a binary version of Functor.map.

    Type parameters

    • A

    • B

    • Z

    Parameters

    • fa: HK<F, A>
    • fb: HK<F, B>
    • f: function
        • (a: A, b: B): Z
        • Parameters

          • a: A
          • b: B

          Returns Z

    Returns HK<F, Z>

product

  • product<A, B>(fa: HK<F, A>, fb: HK<F, B>): HK<F, [A, B]>
  • Captures the idea of composing independent effectful values.

    It is of particular interest when taken together with Functor. Where Functor captures the idea of applying a unary pure function to an effectful value, calling product with map allows one to apply a function of arbitrary arity to multiple independent effectful values.

    This operation is equivalent with:

    map2(fa, fb, (a, b) => [a, b])
    

    Type parameters

    • A

    • B

    Parameters

    • fa: HK<F, A>
    • fb: HK<F, B>

    Returns HK<F, [A, B]>

Legend

  • Module
  • Object literal
  • Variable
  • Function
  • Function with type parameter
  • Index signature
  • Type alias
  • Enumeration
  • Enumeration member
  • Property
  • Method
  • Interface
  • Interface with type parameter
  • Constructor
  • Property
  • Method
  • Index signature
  • Class
  • Class with type parameter
  • Constructor
  • Property
  • Method
  • Accessor
  • Index signature
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Inherited accessor
  • Protected property
  • Protected method
  • Protected accessor
  • Private property
  • Private method
  • Private accessor
  • Static property
  • Static method

Generated using TypeDoc