Rename union type to sum type to complement with product type and change description and example to better match the concept

This commit is contained in:
jethro larson 2017-06-06 13:51:07 -07:00
parent dedffb1663
commit a30176c55c

View file

@ -56,8 +56,9 @@ __Table of Contents__
* [Foldable](#foldable) * [Foldable](#foldable)
* [Traversable](#traversable) * [Traversable](#traversable)
* [Type Signatures](#type-signatures) * [Type Signatures](#type-signatures)
* [Union type](#union-type) * [Algebraic data type](#algebraic-data-type)
* [Product type](#product-type) * [Sum type](#sum-type)
* [Product type](#product-type)
* [Option](#option) * [Option](#option)
* [Functional Programming Libraries in JavaScript](#functional-programming-libraries-in-javascript) * [Functional Programming Libraries in JavaScript](#functional-programming-libraries-in-javascript)
@ -102,9 +103,9 @@ Partially applying a function means creating a new function by pre-filling some
// Helper to create partially applied functions // Helper to create partially applied functions
// Takes a function and some arguments // Takes a function and some arguments
const partial = (f, ...args) => const partial = (f, ...args) =>
// returns a function that takes the rest of the arguments // returns a function that takes the rest of the arguments
(...moreArgs) => (...moreArgs) =>
// and calls the original function with all of them // and calls the original function with all of them
f(...args, ...moreArgs) f(...args, ...moreArgs)
// Something to apply // Something to apply
@ -294,7 +295,7 @@ Math.abs(Math.abs(10))
``` ```
```js ```js
sort(sort(sort([2, 1]))) sort(sort(sort([2,1])))
``` ```
## Point-Free Style ## Point-Free Style
@ -368,7 +369,8 @@ To be a valid category 3 rules must be met:
Since these rules govern composition at very abstract level, category theory is great at uncovering new ways of composing things. Since these rules govern composition at very abstract level, category theory is great at uncovering new ways of composing things.
### Further reading __Further reading__
* [Category Theory for Programmers](https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/) * [Category Theory for Programmers](https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/)
## Value ## Value
@ -519,9 +521,9 @@ Lazy evaluation is a call-by-need evaluation mechanism that delays the evaluatio
```js ```js
const rand = function*() { const rand = function*() {
while (1 < 2) { while (1 < 2) {
yield Math.random() yield Math.random()
} }
} }
``` ```
@ -583,7 +585,7 @@ A monad is an object with [`of`](#pointed-functor) and `chain` functions. `chain
```js ```js
// Implementation // Implementation
Array.prototype.chain = function (f) { Array.prototype.chain = function(f){
return this.reduce((acc, it) => acc.concat(f(it)), []) return this.reduce((acc, it) => acc.concat(f(it)), [])
} }
@ -603,7 +605,7 @@ An object that has `extract` and `extend` functions.
```js ```js
const CoIdentity = (v) => ({ const CoIdentity = (v) => ({
val: v, val: v,
extract () { extract () {
return this.val return this.val
}, },
@ -631,7 +633,7 @@ An applicative functor is an object with an `ap` function. `ap` applies a functi
```js ```js
// Implementation // Implementation
Array.prototype.ap = function (xs) { Array.prototype.ap = function(xs){
return this.reduce((acc, f) => acc.concat(xs.map(f)), []) return this.reduce((acc, f) => acc.concat(xs.map(f)), [])
} }
@ -701,16 +703,16 @@ Make array a setoid:
```js ```js
Array.prototype.equals = function (arr) { Array.prototype.equals = function (arr) {
const len = this.length const len = this.length
if (len !== arr.length) { if (len !== arr.length) {
return false return false
}
for (let i = 0; i < len; i++) {
if (this[i] !== arr[i]) {
return false
} }
} for (let i = 0; i < len; i++) {
return true if (this[i] !== arr[i]) {
return false
}
}
return true
} }
;[1, 2].equals([1, 2]) // true ;[1, 2].equals([1, 2]) // true
@ -773,27 +775,29 @@ __Further reading__
* [Mostly Adequate Guide](https://drboolean.gitbooks.io/mostly-adequate-guide/content/ch7.html#whats-your-type) * [Mostly Adequate Guide](https://drboolean.gitbooks.io/mostly-adequate-guide/content/ch7.html#whats-your-type)
* [What is Hindley-Milner?](http://stackoverflow.com/a/399392/22425) on Stack Overflow * [What is Hindley-Milner?](http://stackoverflow.com/a/399392/22425) on Stack Overflow
## Union type ## Algebraic data type
A union type is the combination of two types together into another one. A composite type made from putting other types together. Two common classes of algebraic types are [sum](#sum-type) and [product](#product-type).
JS doesn't have static types but let's say we invent a type `NumOrString` which is a sum of `String` and `Number`. ### Sum type
A Sum type is the combination of two types together into another one. It is called sum because the number of possible values in the result type is the sum of the input types.
The `+` operator in JS works on strings and numbers so we can use this new type to describe its inputs and outputs:
JavaScript doesn't have types like this but we can use `Set`s to pretend:
```js ```js
// add :: (NumOrString, NumOrString) -> NumOrString // imagine that rather than sets here we have types that can only have these values
const add = (a, b) => a + b const bools = new Set([true, false]);
const halfTrue = new Set(['half-true']);
add(1, 2) // Returns number 3 // The weakLogic type contains the sum of the values from bools and halfTrue
add('Foo', 2) // Returns string "Foo2" const weakLogicValues = new Set([...bools, ...halfTrue])
add('Foo', 'Bar') // Returns string "FooBar"
``` ```
Union types are also known as algebraic types, tagged unions, or sum types. Sum types are sometimes called union types, discriminated unions, or tagged unions.
There's a [couple](https://github.com/paldepind/union-type) [libraries](https://github.com/puffnfresh/daggy) in JS which help with defining and using union types. There's a [couple](https://github.com/paldepind/union-type) [libraries](https://github.com/puffnfresh/daggy) in JS which help with defining and using union types.
## Product type Flow includes [union types](https://flow.org/en/docs/types/unions/) and TypeScript has [Enums](https://www.typescriptlang.org/docs/handbook/enums.html) to serve the same role.
### Product type
A **product** type combines types together in a way you're probably more familiar with: A **product** type combines types together in a way you're probably more familiar with:
@ -801,12 +805,12 @@ A **product** type combines types together in a way you're probably more familia
// point :: (Number, Number) -> {x: Number, y: Number} // point :: (Number, Number) -> {x: Number, y: Number}
const point = (x, y) => ({x: x, y: y}) const point = (x, y) => ({x: x, y: y})
``` ```
It's called a product because the total possible values of the data structure is the product of the different values. It's called a product because the total possible values of the data structure is the product of the different values. Many languages have a tuple type which is the simplest formulation of a product type.
See also [Set theory](https://en.wikipedia.org/wiki/Set_theory). See also [Set theory](https://en.wikipedia.org/wiki/Set_theory).
## Option ## Option
Option is a [union type](#union-type) with two cases often called `Some` and `None`. Option is a [sum type](#sum-type) with two cases often called `Some` and `None`.
Option is useful for composing functions that might not return a value. Option is useful for composing functions that might not return a value.
@ -814,22 +818,22 @@ Option is useful for composing functions that might not return a value.
// Naive definition // Naive definition
const Some = (v) => ({ const Some = (v) => ({
val: v, val: v,
map (f) { map(f) {
return Some(f(this.val)) return Some(f(this.val))
}, },
chain (f) { chain(f) {
return f(this.val) return f(this.val)
} }
}) })
const None = () => ({ const None = () => ({
map (f) { map(f){
return this return this
}, },
chain (f) { chain(f){
return this return this
} }
}) })
// maybeProp :: (String, {a}) -> Option a // maybeProp :: (String, {a}) -> Option a