[go: up one dir, main page]

0% found this document useful (0 votes)
17 views19 pages

Lecture 12

This document discusses the concepts of functors, applicatives, and monads in the context of TypeScript, highlighting their definitions and implementations. It provides iterative and recursive examples for each concept, illustrating how they apply functions to wrapped values and structures. References to Haskell's type classes are made to compare the implementations in TypeScript.

Uploaded by

adobeksm
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views19 pages

Lecture 12

This document discusses the concepts of functors, applicatives, and monads in the context of TypeScript, highlighting their definitions and implementations. It provides iterative and recursive examples for each concept, illustrating how they apply functions to wrapped values and structures. References to Haskell's type classes are made to compare the implementations in TypeScript.

Uploaded by

adobeksm
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 19

Functors, Applicatives and

Monads in TypeScript
About this lecture
• The content (code) discussed in this lecture cover the concepts
of functors, applicatives and monads in the context of Typescript.
However, not everything has strictly been enforced as is done in
Haskell.

2
Functors

3
Functors
A functor applies a function to a wrapped value

4
Functors in Haskell
The type class Functor has only one method namely fmap:

class Functor f where


fmap :: (a -> b) -> f a -> f b

fmap takes
• a function that takes an a and returns a b and
• a box/computational context (list, tree etc.) with an a (or
several of them) inside it.
fmap returns
• a box/computational context (list, tree, etc.) with a b (or several
of them) inside it, i.e., fmap applies the function to each
element inside the context.
Functors: Iterative implementation in TypeScript

function fmap1a(
g: (n: number) => number, data: number[]): number[] {

let output: number[] = [];


A functor applies a
function to a
for (let i = 0; i < data.length; i++) wrapped value
output.push(g(data[i]));

return output;

6
Functors: Recursive implementation in TypeScript

function fmap1b(
g: (n: number) => number, data: number[]): number[] {
A functor applies
function fmap(g: (n: number) => number, data: number[], i: number): number[] { a function to a
if (i == data.length) wrapped value
return [];
return [g(data[i]), ...fmap(g, data, i + 1)];
}
let output: number[] = [];
output = fmap(g, data, 0);
return output; Recursive inner
function
}

7
Functors: Recursive implementation in TypeScript

function fmap1c<T1, T2>(


g: (n: T1) => T2, data: T1[]): T2[] {
A functor applies
function fmap<T1, T2>(g: (n: T1) => T2, data: T1[], i: number): T2[] { a function to a
if (i == data.length) wrapped value
return [];
return [g(data[i]), ...fmap(g, data, i + 1)];
}
let output: T2[] = [];
Generic outer
output = fmap(g, data, 0);
and inner
return output; functions that
} can work on
different types

8
Applicative

9
Applicative
• An applicative applies wrapped functions to wrapped values.

10
Applicative in Haskell
The type class Applicative has the following methods:

• The function pure converts a value of type a into a structure of


type f a. In other words, it stores a plain value in a box/context.
• The function (<*>) has the following property
• The argument function, the argument value and result value
are all contained in a box/context/container
Applicative: Iterative implementation in TypeScript
function apply1a<T1, T2>(
g: ((n: T1) => T2)[], data: T1[]): T2[] {

let output: T2[] = [];


An applicative
applies wrapped
for (let j = 0; j < g.length; j++) functions to
wrapped values.
for (let i = 0; i < data.length; i++)
output.push(g[j](data[i]));

return output;
}
12
Applicative: Recursive implementation in TypeScript

function apply1b<T1, T2>( An applicative


g: ((n: T1) => T2)[], data: T1[]): T2[] { applies wrapped
functions to
wrapped values.
function apply(g: ((n: T1) => T2)[], data: T1[], i: number): T2[] {
if (i == g.length)
return [];
return [...fmap1c(g[i], data), ...apply(g, data, i + 1)];
}
Generic outer
let result = apply(g, data, 0); and inner
return result; functions that
} can work on
different types.

13
Monad

14
Monad
• A Monad applies a "function that returns a wrapped value" to a
wrapped value

15
Monad in Haskell
The type class Monad has the following methods:

By default return = pure, i.e., return is just another name for the
applicative function pure. The function can, however, be
overridden.
Monad: Iterative implementation in TypeScript

function monad1a<T1, T2>


(data: T1[], g: ((n: T1) => T2[])): T2[] {
A Monad applies a
let output: T2[] = []; "function that
returns a wrapped
for (let i = 0; i < data.length; i++) value" to a
output.push(g(data[i])[0]); wrapped value

return output;
}

17
Monad: Recursive implementation in TypeScript

function monad1b<T1, T2>( A Monad applies a


data: T1[], g: ((n: T1) => T2[])): T2[] { "function that
returns a wrapped
function monad(g: (n: T1) => T2[], data: T1[], i: number): T2[] { value" to a
if (i == data.length) wrapped value
return output;
return [g(data[i])[0], ...monad(g, data, i + 1)];
}
let output: T2[] = [];
Generic outer
output = monad(g, data, 0); and inner
return output; functions that
can work on
} different types.

18
References
• Learning TypeScript by Josh Goldberg
• Node.js in Action by Alex Young etc.

19

You might also like