Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation for Identity #330

Merged
merged 8 commits into from
Oct 29, 2018
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
274 changes: 274 additions & 0 deletions docs/src/pages/docs/crocks/Identity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
---
title: "Identity"
description: "Identity Crock"
layout: "guide"
weight: 60
---

```haskell
Identity a
```

`Identity` is one of the most versatile `monads`. Although it does not have any
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worried that this may be to much and going a little to deep on the Category Theory for the average learner.
Could the description be something like:

Identity is a crock that can be used to wrap a common interface around existing Javascript types and functions. It maintains integrity by lifting and applying functions and types as is, without adding any additional structure or effects. By not applying and additional structure to existing functions, Identity can be swapped in and out for other Functors that do apply their own structure and effects.

Or something along those lines. Talk more about usage, then theory. Still give a little theory to put it in context with the other types, but focus more on its usage in the grand scheme of things. Without giving away too much.

(boy that is a wishy-washy suggestion)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha all good. Never thought the roles would be reversed and you'd tell me i was being too theoretical :)

inherant behaviour its power comes from lifting a simple value into the monadic
space and applying the given `function` (`map`/`chain`/etc) to it's value.
`Identity` is often used in place where a `monad` or `applicative` is expected.
Identity is also known the "empty" functor and applicative functor. `Identity`
composed with another functor or applicative functor is isomorphic to the
original.

```javascript
import Identity from 'crocks/Identity'

Identity(10)
//=> Identity 10
```
<article id="topic-implements">

## Implements
`Setoid`, `Semigroup`, `Functor`, `Chain`, `Traversable`, `Apply`, `Applicative`, `Monad`
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This list need to be in order of constraints imposed, so:

Setoid, Semigroup, Functor, Apply, Traversable, Chain, Applicative, Monad


</article>

<article id="topic-construction">

## Construction

```haskell
Identity :: a -> Identity a
```

The contstructor for an `Identity` is a unary function. When a value is passed
in an `Identity` of the given value is returned ready for `map` or `chain`.

```javascript
import Identity from 'crocks/Identity'

const fromComputerCode = String.fromCharCode

Identity(42)
.map(fromComputerCode)
//=> Identity '*'

```

</article>

<article id="topic-constructor">

## Constructor Methods

#### of

```haskell
Identity.of :: a -> Identity a
```

`of` is used to construct an `Identity` with any given value. It is there to
allow `Identity` to function as a pointed functor.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to function -> to work


```javascript
import Identity from 'crocks/Identity'

const { of } = Identity

of(42)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use Identity.of instead, just for consistency since we use in that way in other docs.

//=> Identity 42

of(true)
//=> Identity true

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra newline here, fences should hug the code tightly.

```

</article>

<article id="topic-instance">

## Instance Methods

#### equals

```haskell
Identity a ~> b -> Boolean
```

Used to compare the underlying values of two `Identity` instances for equality by
value, `equals` takes any given argument and returns `true` if the passed
arguments is a `Identity` with an underlying value equal to the underlying value
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a Identity -> an Identity

of the `Identity` the method is being called on. If the passed argument is not
an `Identity` or the underlying values are not equal, `equals` will return `false`.

```javascript
import Identity from 'crocks/Identity'

import equals from 'crocks/pointfree/equals'

Identity(33)
.equals(Identity(33))
//=> true

Identity(33)
.equals(Identity('33'))
//=> false

// by value, not reference for most types
Identity({ a: 86, b: true })
.equals(Identity({ a: 86, b: true }))
//=> true

equals(Identity(95), 95)
//=> false

equals(Identity([ 2, 3 ]), Identity([ 2, 3 ]))
//=> true
```

#### concat

```haskell
Identity s => Identity s ~> Identity s -> Identity s
```

When an underlying value of a given `Identity` is fixed to a `Semigroup`,
`concat` can be used to concat another `Identity` instance with an underlying
`Semigroup` of the same type. Expecting a `Identity` wrapping a `Semigroup` of
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a Identity -> an Identity

the same type, `concat` will give back a new `Identity` instance wrapping the
result of combining the two underlying `Semigroup`s.

```javascript
import Identity from 'crocks/Identity'

import Sum from 'crocks/Sum'

import compose from 'crocks/helpers/compose'
import concat from 'crocks/pointfree/concat'
import flip from 'crocks/combinators/flip'
import map from 'crocks/pointfree/map'
import mapReduce from 'crocks/helpers/mapReduce'
import valueOf from 'crocks/pointfree/valueOf'

// empty :: Identity Sum
const empty =
Identity(Sum.empty())

// sumList :: [ * ] -> Identity Number
const sumList = compose(
map(valueOf),
mapReduce(compose(Identity, Sum), flip(concat), empty)
)

Identity([ 34 ])
.concat(Identity([ 92 ]))
//=> Identity [ 34, 92 ]

sumList([ 3, 4, 5 ])
//=> Identity 12

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra newline (cinima)

```

#### map

```haskell
Identity a ~> (a -> b) -> Identity b
```

Used to apply transformations to values you've lifted into an `Identity`, `map`
takes a function that it will lift into the context of the `Identity` and apply
to it the wrapped value. `Identity` contains no bahaviour and will do nothing
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bahaviour -> behavior

more than apply the value inside the `Identity` to the function.

```javascript
import Identity from 'crocks/Identity'
import map from 'crocks/pointfree/map'

const prod = a => b => a * b

const mapDouble = map(prod(2))

mapDouble(Identity(5))
//=> Identity 10
```

#### ap

```haskell
Identity (a -> b) ~> Identity a -> Identity b
```

`ap` allows for values wrapped in a `Identity` to be applied to functions also
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a Identity -> an Identity

wrapped in a `Identity`. In order to use `ap`, the `Identity` must contain a
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a Identity -> an Identity

function as its value. Under the hood, `ap` unwraps both the function
and the value to be applied and applies the value to the function. Finally it
will wrap the result of that application back into a `Identity`. It is required
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a Identity -> an Identity

that the inner function is curried.

```javascript
import Identity from 'crocks/Identity'

const prod = a => b => a * b
const double = prod(2)

Identity(double)
.ap(5)
//=> Identity 10

```

#### sequence

```haskell
Apply f => Identity (f a) ~> (b -> f b) -> f (Identity a)
Applicative f => Identity (f a) ~> TypeRep f -> f (Identity a)
```

When an instance of `Identity` wraps an `Apply` instance, `sequence` can be used to
swap the type sequence. `sequence` requires either an `Applicative TypeRep` or
an `Apply` returning function is provided for its argument.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is provided -> to be provided
(may need to fix this in a couple places if this was copied)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This came from Maybe. After this commit i'll make that channge


`sequence` can be derived from [`traverse`](#traverse) by passing it an
`identity` function (`x => x`).

```javascript
import Identity from 'crocks/Identity'

import Maybe from 'crocks/Maybe'
import sequence from 'crocks/pointfree/sequence'

// seqId :: Identity Maybe a -> Maybe Identity a
const seqMaybe =
sequence(Maybe)

seqMaybe(Identity(Maybe(42)))
//=> Just Identity 42
```

#### traverse

#### chain

```haskell
Identity a ~> (a -> Identity b) -> Identity b
```

Normally one of the ways `Monad`s like `Identity` are able to be combined and
have their effects applied is through `chain`. However `Identity` is different
because there are no effects to apply. `chain` will simply take a func that
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

func -> function

returns `Identity` and applies it to its value.

```javascript
import Identity from 'crocks/Identity'
import compose from 'crocks/helpers/compose'
import chain from 'crocks/pointfree/chain'

const prod = a => b => a * b
const doubleAsIdentity = compose(Identity, prod(2))

doubleAsIdentity(21)
//=> Identity 42

chain(doubleAsIdentity, Identity(5))
//=> Identity 10

```

</article>
13 changes: 12 additions & 1 deletion docs/src/pages/docs/crocks/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ names, but what they do from type to type may vary.
| [`Const`][const] | -- | [`ap`][const-ap], [`chain`][const-chain], [`concat`][const-concat], [`equals`][const-equals], [`map`][const-map], [`valueOf`][const-valueof] |
| [`Either`][either] | [`Left`][either-left], [`Right`][either-right], [`of`][either-of]| [`alt`][either-alt], [`ap`][either-ap], [`bimap`][either-bimap], [`chain`][either-chain], [`coalesce`][either-coalesce], [`concat`][either-concat], [`either`][either-either], [`equals`][either-equals], [`map`][either-map], [`of`][either-of], [`sequence`][either-sequence], [`swap`][either-swap], [`traverse`][either-traverse] |
| [`Equiv`][equiv] | [`empty`][equiv-empty] | [`concat`][equiv-concat], [`contramap`][equiv-contra], [`compareWith`][equiv-compare], [`valueOf`][equiv-value] |
| `Identity` | `of` | `ap`, `chain`, `concat`, `equals`, `map`, `of`, `sequence`, `traverse`, `valueOf` |
| [`Identity`][identity] | [`of`][identity-of] | [`ap`][identity-ap], [`chain`][identity-chain], [`concat`][identity-concat], [`equals`][identity-equals], [`map`][identity-map], [`of`][identity-of], [`sequence`][identity-sequence], [`traverse`][identity-traverse], [`valueOf`][identity-valueOf] |
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

link refs should be all lowercase:

identity-valueOf -> identity-valueof

also missing the identity-valueof ref below.

| `IO` | `of` | `ap`, `chain`, `map`, `of`, `run` |
| `List` | `empty`, `fromArray`, `of` | `ap`, `chain`, `concat`, `cons`, `empty`, `equals`, `filter`, `fold`, `foldMap`, `head`, `map`, `of`, `reduce`, `reduceRight`, `reject`, `sequence`, `tail`, `toArray`, `traverse`, `valueOf` |
| [`Maybe`][maybe] | [`Nothing`][maybe-nothing], [`Just`][maybe-just], [`of`][maybe-of], [`zero`][maybe-zero] | [`alt`][maybe-alt], [`ap`][maybe-ap], [`chain`][maybe-chain], [`coalesce`][maybe-coalesce], [`concat`][maybe-concat], [`equals`][maybe-equals], [`either`][maybe-either], [`map`][maybe-map], [`of`][maybe-of], [`option`][maybe-option], [`sequence`][maybe-sequence], [`traverse`][maybe-traverse], [`zero`][maybe-zero] |
Expand Down Expand Up @@ -95,6 +95,17 @@ names, but what they do from type to type may vary.
[either-swap]: Either.html#swap
[either-traverse]: Either.html#traverse

[identity]: Identity.html
[identity-of]: Identity.html#of
[identity-alt]: Identity.html#alt
[identity-ap]: Identity.html#ap
[identity-chain]: Identity.html#chain
[identity-concat]: Identity.html#concat
[identity-equals]: Identity.html#equals
[identity-map]: Identity.html#map
[identity-sequence]: Identity.html#sequence
[identity-traverse]: Identity.html#traverse

[equiv]: Equiv.html
[equiv-empty]: Equiv.html#empty
[equiv-concat]: Equiv.html#concat
Expand Down