Kleisli is a clean Ruby implementation of some structures we find naturally in the world of functional programming. In this post we'll explore how to effectively structure computations and pipelines using Kleisli in Ruby.

## Functor

In the words of the Haskell documentation, a "Functor" can be mapped over. A simple example of this is a list. Many Ruby programmers will be familiar with code like `my_list.map { ... }`

. Functor lets us extend this idea further.

First off, let's rewrite a "map" type function for a linked list structure and call it `fmap`

.

```
require 'kleisli'
class Node < Kleisli::Functor
def initialize(val, nextNode)
@val, @nextNode = val, nextNode
end
def fmap(&f)
# Look ma! No nil checks!
Node.new(f.call(@val), @nextNode.fmap(&f))
end
end
# ...
Node.new(1, Node.new(2, None())).fmap { |x| x + 1 }
# => #<Node
# @val=2,
# @nextNode=#<Node
# @val=3,
# @nextNode=None>>
```

We don't just `fmap`

over lists though, we can map over fail-y values and other Functors:

```
Maybe(1).fmap { |x| x + 1 }.fmap { |x| x + 2 }
# => Some(4)
None().fmap { |x| + 1 }.fmap { |x| x + 2 }
# => None
```

So Functor is a pretty generic term involving the notion of "mapping" a function over a value.

## Applicative Functor

Sometimes you'll hear references to "wrapping values" as an intuition for Functors. This can be a useful (but limited) metaphor. Applicative Functors let us "wrap" functions too. The `*`

operator is used to combine things here using Kleisli:

```
Some(-> x, y { x + y }) * Some(1) * Some(2)
# => Some(3)
```

Introducing failures anywhere will cause the whole computation to fail:

```
# Apply a non existent function to two arguments
None() * Some(1) * Some(2)
# => None
# Apply a function to some missing arguments:
Some(-> x, y { x + y }) * None() * Some(2)
# => None
```

Once you get used to it, this provides an alternative to manual error-checking and nil-checking.

## Monads

Monads are one step further. With a Monad we can build a pipeline of computations. We'll use the Either monad - which uses a Left constructor to indicate failure and a Right constructor to indicate success. Let's find the average of the even numbers in a list, then format it into a message:

```
def average_of_evens(list)
Right(list.find_all(&:even?)) >-> subList {
size = subList.count
if size.zero?
Left("There are no evens!")
else
sum = subList.inject(:+).to_f
Right(sum / size)
end
} >-> result {
Right("The average of the evens is: #{result}")
}
end
average_of_evens([1,3,5])
# => Left("There are no evens!")
average_of_evens([1,2,3,4,5,6])
# => Right("The average of the evens is: 4.0")```
```

## Caveats

Ruby won't stop you writing code such as:

```
None() + 1
# => NoMethodError: undefined method `+' for None:Kleisli::Maybe::None
```

When what you wanted was fmap:

```
None().fmap { |x| x + 1 }
# => None
```

For that we'd need a type-checker or some other sophisticated static analysis. Additionally writing programs with Kleisli could not be considered idiomatic. However it is still a valid alternative in certain contexts where manual error checking and function composition is tiresome and error-prone.