---
category: tutorial
title: maybe
layout: post
---

The `maybe` type, also known as `option` type is a container for a value that may not be there. 

The purpose of this monad is to eliminate the need for writing `null` checks. 
Furthermore it also eliminates the possibility of making errors by missing null-checks.

<!--more-->





To use the `maybe` monad constructor, you can require it using node:
		
		var maybe = require("../library/maybe")


Where the `../` is the location of the module.

Then you will be able to wrap a value in `maybe` with:

		var maybe_val = maybe(val)

If the 'val' is equal to *undefined* it threats the container as empty.


`map(funk)`
----
Executes `funk` with the `maybe`'s value as an argument, but only if the value is different from *undefined*, and wraps the result in a new maybe.

***



Traditionally, if we have a value that may be undefined we do a null check before doing something with it:



	
	var val = get_property(obj)
	
	if(val !== undefined){
		val = val.toString()
	}
	assert.equal(val, undefined) 

With `map` this can be written like this

 	var maybe_get_property = get_property.map(maybe)

	maybe_get_property(obj).map((val) => {

		val.toString()//this is not executed
	})

The biggest benefit we get is that in the first case we can easily forget the null check:
	
	assert.throws(function(){
		get_property(obj).toString()  //this blows up
	})

While in the second case we cannot access the underlying value directly, and therefore cannot execute an action on it, if it is not there.




`phatMap(funk)`
----

Same as `map`, but if `funk` returns a `maybe` it flattens the two `maybes` into one.

***




`map` works fine for eliminating errors, but it does not solve one of the most annoying problems with null-checks - nesting:

	var obj = { first: {second:"val" } }
	
	maybe(obj)
		.map( root => maybe(root.first))
		.map( maybeFirst => maybeFirst.map (first => maybe (maybeFirst.second ) ) ) 
		.map( maybeMaybeValue => maybeMaybeValue.map (maybeValue => maybeValue.map( (value)=>( assert.equal( val, "val") ) ) ) )

`phatMap` does the flattening for us, and allows us to write code like this

	maybe(obj)
		.flatMap(root => maybe(root.first))
		.flatMap(first => maybe(first.second))
		.flatMap(val => {
			assert.equal(val, "val")
		})




Advanced Usage
----



 `maybe` can be used with the function monad to effectively produce 'safe' versions of functions

	var get = f((prop, obj) => obj[prop])
	var maybeGet = get.map(maybe)

This combined with the use of currying makes for a very fluent style of coding:

	var getFirstSecond = (root) => maybe(root).phatMap(maybeGet('first')).phatMap(maybeGet('second'))
	
	getFirstSecond({ first: {second:"value" } }).map((val) => assert.equal(val,"value"))
	getFirstSecond({ first: {second:"other_value" } }).map((val) => assert.equal(val,"other_value"))
	getFirstSecond({ first: "" }).map((val) => assert.equal(val,"whatever") )//won't be executed 





under the hood
--------------
Let's see how the type is implemented







The `of` method, takes a value and wraps it in a `maybe`.
In this case we do this by just calling the constructor.

	//a -> m a
	of:function(input){
		return maybe(input)
	},

`map` takes the function and applies it to the value in the maybe, if there is one.

	//m a -> ( a -> b ) -> m b
	map:function(funk){
		if(this !== nothing){
			return maybe(funk(this._value))
		}else{	
			return this 
		}
	},

`flat` takes a maybe that contains another maybe and flattens it.
In this case this means just returning the inner value.

	//m (m x) -> m x
	flat:function(){
		if(this !== nothing){
			return this._value
		}else{
			return this
		}
	},

finally we have `tryFlat` which does the same thing, but checks the types first. The shortcut to `map().tryFlat()` is called `phatMap` 

	tryFlat:function(){
		if(this !== nothing && this._value.constructor === maybe){
			return this._value
		}else{
			return this
		}
	},
	


Finally, the type has some helper functions:

	filter:function(funk){
		return funk(this._value) ? this : nothing
	},

	reduce:function(funk){
		return funk(this._value)
	},

	get:function(prop){
		return maybe(this._value[prop])
	}


	


In case you are interested, here is how the maybe constructor is implemented


	var maybe = function(value){
		if (value === undefined){
			return nothing
		}else{
			var obj = Object.create(maybe_proto)
			obj._value = value
			obj.constructor = maybe
			Object.freeze(obj)
			return obj
		}
	}







