Created
March 21, 2015 20:49
-
-
Save AGhost-7/a6e416b322b2b0a75d02 to your computer and use it in GitHub Desktop.
Effect Monad?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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