Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/alex-lairan/monads
Monads for Crystal
https://github.com/alex-lairan/monads
crystal crystal-language monads
Last synced: about 1 month ago
JSON representation
Monads for Crystal
- Host: GitHub
- URL: https://github.com/alex-lairan/monads
- Owner: alex-lairan
- License: mit
- Created: 2018-10-14T21:02:02.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2022-10-14T07:01:37.000Z (about 2 years ago)
- Last Synced: 2024-10-25T01:26:03.612Z (about 2 months ago)
- Topics: crystal, crystal-language, monads
- Language: Crystal
- Homepage: https://github.com/alex-lairan/monads
- Size: 113 KB
- Stars: 46
- Watchers: 7
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-crystal - monads - Monad implementation (Misc)
- awesome-crystal - monads - Monad implementation (Misc)
README
# monads
[![Build Status](https://travis-ci.org/alex-lairan/monads.svg?branch=master)](https://travis-ci.org/alex-lairan/monads)Monads for Crystal.
Inspired by https://github.com/dry-rb/dry-monads
## Installation
Add this to your application's `shard.yml`:
```yaml
dependencies:
monads:
github: alex-lairan/monads
```## Usage
```crystal
require "monads"
```Many monads exist.
### Maybe(T)
The *Maybe* monad helps to avoid `nil` and chain instructions.
There are two kinds of *Maybe*, `Just` and `Nothing`.
#### Just(T)
This is just a value.
```crystal
Monads::Just.new(5)
```#### Nothing(T)
This is an absence of value.
```crystal
Monads::Nothing(Int32).new
```### Either(E, T)
The *Either* monad helps to manage *errors* at the end of the chain of instructions.
There are two kinds 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 helps to manipulate an *Array* like a monad.
```crystal
Monads::List[1, 6, 4, 2]
```#### head
`head` returns the first element wrapped within 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 which help to chain instructions.
`Try` and `Task` monads should be translated into a `Maybe(T)` or an `Either(Exception, T)` one.
#### fmap
The `fmap` procedure modify the 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 allows to create a whole new monad 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
Clone then let's go, no special requirements.
## Contributing
1. Fork it ()
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request## Contributors
- [alex-lairan](https://github.com/alex-lairan) Alexandre Lairan - creator, maintainer
- [moba1](https://github.com/moba1) moba - maintainer