Skip to content

Instantly share code, notes, and snippets.

@AGhost-7
Created March 21, 2015 20:49
Show Gist options
  • Save AGhost-7/a6e416b322b2b0a75d02 to your computer and use it in GitHub Desktop.
Save AGhost-7/a6e416b322b2b0a75d02 to your computer and use it in GitHub Desktop.
Effect Monad?
class Effect
constructor: (@object, @sideEffect) ->
map: (func) ->
copy = clone(@object)
@sideEffect(copy)
new Effect(copy, func)
flatMap: (func) ->
copy = clone(@object)
@sideEffect(copy)
func(copy)
flatten: ->
copy = clone(@object)
@sideEffect(copy)
copy
@applicator = (func) ->
(obj) ->
new Effect(obj, func)
clone = (object) ->
copy = new Object
for key of object
member = object[key]
if typeof member == 'object'
if Array.isArray member
copy[key] = member.slice(0)
else if member instanceof Date
# since date is a mutable object, we need to clone it as well
copy[key] = new Date(member)
else
copy[key] = clone(member)
else
# rest of these are immutable (including functions), therefore we can
# simply add to the new object.
copy[key] = member
copy
class Person
constructor: (@name, @age)->
@hp = 10
me = new Person('Jonathan', 22)
agePerson = Effect.applicator (person) ->
person.age += 20
addBoudreau = Effect.applicator (person) ->
person.name += ' Boudreau'
agedMe = agePerson(me)
withLastName = agedMe.map (person) ->
person.name += ' Boudreau'
withLastNameApplicator = agedMe.flatMap(addBoudreau)
console.log(me)
console.log(agedMe.flatten())
console.log(withLastName.flatten())
console.log(withLastNameApplicator.flatten())
# >{ name: 'Jonathan', age: 22, hp: 10 }
# >{ name: 'Jonathan', age: 42, hp: 10 }
# >{ name: 'Jonathan Boudreau', age: 42, hp: 10 }
# >{ name: 'Jonathan Boudreau', age: 42, hp: 10 }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment