Skip to content

Instantly share code, notes, and snippets.

@thinca
Created November 17, 2009 16:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thinca/237040 to your computer and use it in GitHub Desktop.
Save thinca/237040 to your computer and use it in GitHub Desktop.
" Maybe Monad
let Maybe = {}
function! Maybe.return(m)
return Just(a:m)
endfunction
" m(self) >>= f
function! Maybe.bind(f)
let Func = type(a:f) == type('') ? function(a:f) : a:f
return self['bind_' . self.type](Func)
endfunction
function! Maybe.bind_Just(f)
return a:f(self.m)
endfunction
function! Maybe.bind_Nothing(_)
return Nothing()
endfunction
function! Maybe.show()
return self['show_' . self.type](self)
endfunction
function! Maybe.show_Just(m)
return 'Maybe "' . a:m.m.show() . '"'
endfunction
function! Maybe.show_Nothing(_)
return 'Nothing'
endfunction
function! Maybe.fail(_)
return Nothing()
endfunction
function! Just(m)
return extend(copy(g:Maybe), {'type': 'Just', 'm': a:m})
endfunction
function! Nothing()
return extend(copy(g:Maybe), {'type': 'Nothing'})
endfunction
" -- Sheep
function! Sheep(name, mother, father)
let sheep = {'name': a:name, 'mother': a:mother, 'father': a:father}
function! sheep.show() " Helper function
return self.name
endfunction
return sheep
endfunction
function! Name(sheep)
return a:sheep.name
endfunction
function! Mother(sheep)
return a:sheep.mother
endfunction
function! Father(sheep)
return a:sheep.father
endfunction
function! FmaternalGrandfather(sheep)
return g:Maybe.return(a:sheep).bind('Mother').bind('Father')
endfunction
function! FfathersMaternalGrandmother(sheep)
return g:Maybe.return(a:sheep).bind('Father').bind('Mother').bind('Mother')
endfunction
function! FmothersPaternalGrandfather(sheep)
return g:Maybe.return(a:sheep).bind('Mother').bind('Father').bind('Father')
endfunction
let breedSheep = {}
let breedSheep.adam = Sheep("Adam", Nothing(), Nothing())
let breedSheep.eve = Sheep("Eve", Nothing(), Nothing())
let breedSheep.uranus = Sheep("Uranus", Nothing(), Nothing())
let breedSheep.gaea = Sheep("Gaea", Nothing(), Nothing())
let breedSheep.kronos = Sheep("Kronos", Just(breedSheep.gaea), Just(breedSheep.uranus))
let breedSheep.holly = Sheep("Holly", Just(breedSheep.eve), Just(breedSheep.adam))
let breedSheep.roger = Sheep("Roger", Just(breedSheep.eve), Just(breedSheep.kronos))
let breedSheep.molly = Sheep("Molly", Just(breedSheep.holly), Just(breedSheep.roger))
let dolly = Sheep("Dolly", Just(breedSheep.molly), Nothing())
echo FmaternalGrandfather(dolly).show()
echo FfathersMaternalGrandmother(dolly).show()
echo FmothersPaternalGrandfather(dolly).show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment