Skip to content

Commit 6fc6540

Browse files
committed
Merge pull request hemanth#21 from jethrolarson/master
Updated Isomorphic and Monad.
2 parents d7493fa + ed415a1 commit 6fc6540

File tree

1 file changed

+103
-13
lines changed

1 file changed

+103
-13
lines changed

readme.md

Lines changed: 103 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ partial(2); //=> 42
6565
> The process of converting a function with multiple arity into the same function with an arity of one. Not to be confused with partial application, which can produce a function with an arity greater than one.
6666
6767
```js
68-
let sum = (a,b) => a+b;
68+
let sum = (a, b) => a + b;
6969

7070
let curriedSum = (a) => (b) => a + b;
7171

@@ -133,13 +133,13 @@ let add = (a, b) => a + b;
133133
// Not points-free - `numbers` is an explicit parameter
134134
let incrementAll = (numbers) => map(add(1))(numbers);
135135

136-
// Points-free - The array is an implicit parameter
136+
// Points-free - The list is an implicit parameter
137137
let incrementAll2 = map(add(1));
138138
```
139139

140-
`total1` lists and uses the parameter `numbers`, so it is not points-free. `total2` is written just by combining functions and values, making no mention of its arguments. It __is__ points-free.
140+
`incrementAll` identifies and uses the parameter `numbers`, so it is not points-free. `incrementAll2` is written just by combining functions and values, making no mention of its arguments. It __is__ points-free.
141141

142-
It is easy to recognize points-free function definitions; they are the ones that contain no '`function`' keywords and no fat arrows.
142+
Points-free function definitions look just like normal assignments without `function` or `=>`.
143143

144144
---
145145

@@ -269,12 +269,27 @@ The identity value is empty array `[]`
269269

270270
## Monad
271271

272-
> A monad is a container type that provides two functions, [chain](#chain) and [ap](#applicative-functor). Monads provide an interface for executing a common sequence of commands on a particular kind of value, often one you want to avoid acting on directly. One of the most common monads is the "maybe" or optional value monad, which wraps a value that could be either nothing or something. By using a monad instead of the raw value, you can protect your code from exposure to null values. Likewise, a "state" monad can be used in a parser to algorithmically consume an input string using a repeatable sequence of steps that preserves the current state of the input from operation to operation. Also, since a monad is, by definition, a special kind of functor that also returns a monad, they can be chained together to describe any sequence of operations. In functional languages with lazy evaluation, monads are used where sequence of evaluation is important, such as in I/O. Due to this sequencing utility, they are sometimes referred to as "programmable semicolons."
272+
> A monad is a container type that provides two functions, [chain](#chain) and `of`. Monads provide an interface for executing a common sequence of commands on a particular kind of value, often one you want to avoid acting on directly. One of the most common monads is the "maybe" or optional value monad, which wraps a value that could be either nothing or something. By using a monad instead of the raw value, you can protect your code from exposure to null values. Likewise, a "state" monad can be used in a parser to algorithmically consume an input string using a repeatable sequence of steps that preserves the current state of the input from operation to operation. Also, since a monad is, by definition, a special kind of functor that also returns a monad, they can be chained together to describe any sequence of operations. In functional languages with lazy evaluation, monads are used where sequence of evaluation is important, such as in I/O. Due to this sequencing utility, they are sometimes referred to as "programmable semicolons."
273273

274274
The simplest monad is the Identity monad. It simply wraps a value.
275275

276276
```js
277-
let Identity = v => ({ chain: transform => transform(v) })
277+
let Identity = v => ({
278+
val: v,
279+
chain: transform => transform(this.val),
280+
of: v => this.val
281+
})
282+
283+
// Function that increments value and then wraps with Identity.
284+
let increment = v => Identity(v + 1)
285+
286+
// Use chain to apply function to wrapped values
287+
let incrementIdentity = id => id.chain(increment)
288+
289+
incrementIdentity(Identity(1)) // Identity(2)
290+
291+
//Contrast to using a map, where increment would cause nested Identities
292+
id.map(increment) // Identity(Identity(2))
278293
```
279294

280295
---
@@ -291,6 +306,25 @@ let Identity = v => ({ chain: transform => transform(v) })
291306

292307
## Comonad
293308

309+
> A container type that has `extract` and `extend` functions.
310+
311+
```js
312+
let CoIdentity = v => ({
313+
val: v,
314+
extract: this.v,
315+
extend: f => f(this)
316+
})
317+
```
318+
319+
Extract takes a value out of a container. Essentially it's the opposite of `of`.
320+
```js
321+
CoIdentity(1).extract() // 1
322+
```
323+
324+
Extend runs a function on the comonad. The function should return the same type as the Comonad.
325+
```js
326+
CoIdentity(1).extend(co => co.extract() + 1) // CoIdentity(2)
327+
```
294328
---
295329

296330
## Applicative Functor
@@ -309,36 +343,92 @@ let Identity = v => ({ chain: transform => transform(v) })
309343

310344
## Isomorphic
311345

312-
> Two objects are Isomorphic is they satisfy the condition: `compose(to, from) == Identity` and `compose(from, to) == Identity`
346+
> Two objects are Isomorphic is they satisfy the condition: `compose(to, from) == identity` and `compose(from, to) == identity`
313347
314348
```js
315-
const toChars = [].join;
349+
const pairToCoords = (arr) => ({x: arr[0], y: arr[1]})
316350

317-
const fromChars = ''.split;
351+
const coordsToPair = (coords) => [coords.x, coords.y]
318352

319-
fromChars.call(toChars.call([1,2,3])) // [ '1,2,3' ]
353+
coordsToPair(pairToCoords([1, 2])) // [1, 2]
320354

321-
toChars.call(fromChars.call([1,2,3])) // '1,2,3'
355+
pairToCoords(coordsToPair({x: 1, y: 2})) // {x: 1, y: 2}
322356
```
323357

324358
---
325359

326360
## Setoid
327361

362+
> An object that has an `equals` function which can be used to compare other objects of the same type.
363+
364+
Make array a setoid.
365+
```js
366+
Array.prototype.equals = arr => {
367+
var len = this.length
368+
if (len != arr.length) {
369+
return false
370+
}
371+
for (var i = 0; i < len; i++) {
372+
if (this[i] !== arr[i]) {
373+
return false
374+
}
375+
}
376+
return true
377+
}
378+
379+
[1, 2].equals([1, 2]) // true
380+
[1, 2].equals([0]) // false
381+
```
382+
328383
---
329384

330385
## Semigroup
331386

387+
An object that has a `concat` function that combines it with another object of the same type.
388+
389+
```js
390+
[1].concat([2]) // [1, 2]
391+
```
392+
332393
---
333394

334395
## Foldable
335396

397+
> An object that has a reduce function that can transform that object into some other type.
398+
399+
```js
400+
let sum = list => list.reduce((acc, val) => acc + val, 0);
401+
sum([1, 2, 3]) // 6
402+
```
403+
336404
---
337405

338406
## Traversable
339407

340408
---
409+
## Type Signatures
341410

342-
## Comonad
411+
> Often functions will include comments that indicate the types of their arguments and return types.
343412
344-
---
413+
There's quite a bit variance across the community but they often follow the following patterns:
414+
```js
415+
// functionName :: firstArgType -> secondArgType -> returnType
416+
417+
// add :: Number -> Number -> Number
418+
let add = x => y => x + y
419+
420+
// increment :: Number -> Number
421+
let increment = x => x + 1
422+
```
423+
424+
If a function accepts another function as an argument it is wrapped in parenthesis.
425+
426+
```js
427+
// call :: (a -> b) -> a -> b
428+
let call = f => x => f(x)
429+
```
430+
The letters `a`, `b`, `c`, `d` are used to signify that the argument can be of any type. For this map it takes a function that transforms a value of some type `a` into another type `b`, an array of values of type `a`, and returns an array of values of type `b`.
431+
```js
432+
// map :: (a -> b) -> [a] -> [b]
433+
let map = f => list => list.map(f)
434+
```

0 commit comments

Comments
 (0)