Dart Functors, Applicatives, And Monads In Pictures

/// The Maybe type encapsulates an optional value.
/// Using Maybe is a good way to deal with errors or
/// exceptional cases without resorting to
/// drastic measures such as error.

abstract class Maybe<T> {}
/// Represents a value of type Maybe that contains a value
/// (represented as Just a).
class Just<T> extends Maybe<T> {
Just(this.value);
final T value;
}
/// Represents an empty Maybe that holds nothing
/// (in which case it has the value of Nothing)
class Nothing<T> extends Maybe<T> {}

Functors

num plus3(num x) => x + 3;Just(2).fmap(plus3); // Just 5

Just what is a Functor, really?

abstract class Functor<T> {
Functor<U> fmap<U>(U Function(T) f);
}
Just(2).fmap(plus3); // Just 5
abstract class Maybe<T> implements Functor<T> {}class Just<T> extends Maybe<T> {

@override
Maybe<U> fmap<U>(U Function(T) f) => Just(f(value));
}
class Nothing<T> extends Maybe<T> {
@override
Maybe<U> fmap<U>(U Function(T) f) => Nothing();
}
Nothing<num>().fmap(plus3); // Nothing
Bill O’Reilly being totally ignorant about the functor
final post = Post.findByID(1);
if (post != null) {
return post.title;
} else {
return null;
}
final getPostTitle = (Post post) => post.title;
return Post.findByID(42).fmap(getPostTitle);
[2, 4, 6].map((x) => x + 3); // [5, 7, 9]
Iterable<T> map<T>(T toElement(E e)) => MappedIterable<E, T>(this, toElement);
fmap((x) => x + 3, (x) => x + 2);
typedef IntFunction = int Function(int);IntFunction fmap(IntFunction f, IntFunction g) => (x) => f(g(x));final foo = fmap((x) => x + 3, (x) => x + 2);
foo(10); // 15

Applicatives

abstract class Applicative<T> {  Applicative<U> apply<U>(Applicative<U Function(T)> f);}abstract class Maybe<T> implements …, Applicative<T> {}class Just<T> extends Maybe<T> {

@override
Maybe<U> apply<U>(covariant Maybe<U Function(T)> f) => f.fmap((ff) => ff(value)) as Maybe<U>;
}
class Nothing<T> extends Maybe<T> {

@override
Maybe<U> apply<U>(covariant Maybe<U Function(T)> f) => Nothing();
}
Just(2).apply(Just((x) => x + 3)); // Just 5
extension ApplicativeList on List {
Iterable<U> apply<T, U>(List<U Function(T)> list) sync* {
for (final item in list) {
for (var i = 0; i < length; i++) {
yield item(this[i]);
}
}
}
}
[1, 2, 3].apply<int, int>([
(x) => x * 2,
(x) => x + 3,
]); // [2, 4, 6, 4, 5, 6]
final curriedAddition = (num x) => (num y) => x + y;
final a = Just(3).fmap(curriedAddition); // Just<(int) => int>
Just(5).fmap(a); // COMPILATION ERROR
//??? WHAT DOES THIS EVEN MEAN WHY IS THE FUNCTION WRAPPED IN A JUST
Just(5).apply(a); // Just 8
final curriedTimes = (int x) => (int y) => x * y;
Just(5).apply(Just(3).fmap(curriedTimes)); // Just 15

Monads

  1. Get a PhD in computer science.
  2. Throw it away because you don’t need it for this section!
Maybe<num> half(num a) => a % 2 == 0 ? Just(a / 2) : Nothing();
Just(3).bind(half); // Nothing
Just(4).bind(half); // Just 2
Nothing<num>().bind(half); // Nothing
abstract class Monad<T> {
Maybe<U> bind<U>(Maybe<U> Function(T) f);
}
abstract class Maybe<T> implements ..., Monad<T> {}class Just<T> extends Maybe<T> {

@override
Maybe<U> bind<U>(covariant Maybe<U> Function(T) f) => f(value);
}
class Nothing<T> extends Maybe<T> {
@override
Maybe<U> bind<U>(covariant Maybe<U> Function(T) f) => Nothing();
}
Just(20).bind(half).bind(half).bind(half); // Nothing

Conclusion

  1. A functor is a data type that implements the Functor abstract class.
  2. An applicative is a data type that implements the Applicative abstract class.
  3. A monad is a data type that implements the Monad abstract class.
  4. A Maybe implements all three, so it is a functor, an applicative, and a monad.
  • functors: you apply a function to a wrapped value using fmap
  • applicatives: you apply a wrapped function to a wrapped value using apply
  • monads: you apply a function that returns a wrapped value, to a wrapped value using bind.

--

--

--

Mobile developer

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Naming Satalia: What does Satalia mean?

How much will it cost to build an educational app?

Exploring Binary Search Trees

Java 13 — New enhanced switch

AWS Lambda Hands-On| Part-3

AVL Trees — Get rid of linked lists in the BSTs

Transforming Organizations with Cloud-Native Development

Procore now integrates with SharePoint

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store

Oleksandr Leushchenko

Mobile developer

More from Medium

Mutability and immutability in Dart: Understanding var, const and final

The power of a Flutter module in a native App

How to debug code dependencies on VS code

Searching a bug

DART PROGRAMMING LANGUAGE