Skip to content

Commit

Permalink
Merge pull request #48 from alex-lairan/feature/update_readme
Browse files Browse the repository at this point in the history
Update readme
  • Loading branch information
alex-lairan committed May 20, 2019
2 parents a603c2d + 2828c41 commit 6dbe45f
Showing 1 changed file with 109 additions and 1 deletion.
110 changes: 109 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,114 @@ dependencies:
require "monads"
```

TODO: Write usage instructions here
Many monads exists.

### Maybe(T)

The *Maybe* monad help to avoid `nil` and chain instructions.

There is two kind of *Maybe*, `Just` and `Nothing`.

#### Just(T)

This is just a value.

```crystal
Monads::Just.new(5)
```

#### Nothing(T)

This a absance of value.

```crystal
Monads::Nothing(Int32).new
```

### Either(E, T)

The *Either* monad help to manage *errors* at the end of the chain instruction.

There is two kind of *Either*, `Right` and `Left`.

#### Right(T)

This is just a value.

```crystal
Monads::Right.new("Hello world")
```

#### Left(E)

This is an error.

```crystal
Monads::Left.new("User password is incorrect")
```

### List(T)

The *List* monad help to manipulate an *Array* like a monad.

```crystal
Monads::List[1, 6, 4, 2]
```

#### head

`head` returns the first element wrapped with a `Maybe`.

#### tail

`tail` returns the list without the first element.

### Try(T)

The `Try` monad is a layer between *Object Oriented Exception* and *Fuctional Programming Monads*.
It can be transformed into a `Maybe` or an `Either`.

### Task(T)

The `Task` monad is a parallelized `Try` monad.
Its goal is to use the power of fibers with monads.

### How to use a monad ?

Monads have some methods who help to chain instructions.

ps: `Try` and `Task` monads should be translated into a `Maybe(T)` of an `Either(Exception, T)` one.

#### fmap

The `fmap` procedure modify internal value of a monad.

This doesn't affect `Nothing` and `Left` monads.

Example :

```crystal
value = Monads::Just.new(5)
.fmap(->(x : Int32) { x.to_s })
.fmap(->(x : String) { x + "12" })
.fmap(->(x : String) { x.to_i })
.value!
value.should eq(512)
```

#### bind

The `bind` procedure allow to create a whole new monads from the internal data of another.

This doesn't affect `Nothing` and `Left` monads.

Example :

```crystal
value = Monads::Just.new(5)
.bind(->(x : Int32) { Monads::Try(Int32).new(-> { x / 0}).to_maybe })
value.should eq(Monads::Nothing(Int32).new)
```

## Development

Expand All @@ -38,3 +145,4 @@ Clone then let's go, no special requirements.
## Contributors

- [alex-lairan](https://github.com/alex-lairan) Alexandre Lairan - creator, maintainer
- [moba1](https://github.com/moba1) moba - maintainer

0 comments on commit 6dbe45f

Please sign in to comment.