Created
December 2, 2019 07:42
-
-
Save gaku-sei/434d4de22dd66402728542cb9c3c7d35 to your computer and use it in GitHub Desktop.
Play with Indexed Monad in ReasonML (implements https://qiita.com/kimagure/items/a0ee7313e8c7690bf3f5)
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
open! IndexedBurger; | |
let burgerSpec: ixBurger(ready, topBunOn, burgerSpec) = | |
Infix.( | |
getEmptyPlate | |
>>=: placeEmptyBun | |
>>=: addKetchup | |
>>=: addPatty | |
>>=: addCheese | |
>>=: addTopBun | |
); |
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
[@bs.deriving accessors] | |
type ixBurger('x, 'y, 'spec) = | |
| IxBurger('spec); | |
module IxFunctor: | |
Interfaces.IX_FUNCTOR with type t('x, 'y, 'a) = ixBurger('x, 'y, 'a) = { | |
type t('x, 'y, 'a) = ixBurger('x, 'y, 'a); | |
let imap = (f, IxBurger(spec)) => IxBurger(f(spec)); | |
}; | |
module IxApply: | |
Interfaces.IX_APPLY with type t('x, 'y, 'a) = ixBurger('x, 'y, 'a) = { | |
include IxFunctor; | |
let iapply = (IxBurger(f), IxBurger(spec)) => IxBurger(f(spec)); | |
}; | |
module IxApplicative: | |
Interfaces.IX_APPLICATIVE with type t('x, 'y, 'a) = ixBurger('x, 'y, 'a) = { | |
include IxApply; | |
let ipure = ixBurger; | |
}; | |
module IxMonad: | |
Interfaces.IX_MONAD with type t('x, 'y, 'a) = ixBurger('x, 'y, 'a) = { | |
include IxApplicative; | |
let ibind = (IxBurger(spec), f) => | |
f(spec) |> ((IxBurger(spec)) => spec) |> ixBurger; | |
}; | |
module Infix = { | |
include Infix.IxFunctor(IxFunctor); | |
include Infix.IxApply(IxApply); | |
include Infix.IxApplicative(IxApplicative); | |
include Infix.IxMonad(IxMonad); | |
}; | |
// Specific functions | |
let getEmptyPlate: ixBurger(ready, emptyPlate, burgerSpec) = IxBurger([]); | |
let addIngredient: (string, burgerSpec) => ixBurger('i, 'o, burgerSpec) = | |
(x, xs) => ixBurger([Ingredient(x), ...xs]); | |
let placeEmptyBun: | |
burgerSpec => ixBurger(emptyPlate, bottomBunOn, burgerSpec) = | |
addIngredient("Bottom bun"); | |
let addKetchup: burgerSpec => ixBurger(bottomBunOn, bottomBunOn, burgerSpec) = | |
addIngredient("Ketchup"); | |
let addPatty: burgerSpec => ixBurger(bottomBunOn, pattyOn, burgerSpec) = | |
addIngredient("Patty"); | |
let addCheese: burgerSpec => ixBurger(pattyOn, cheeseOn, burgerSpec) = | |
addIngredient("Cheese"); | |
let noCheese: burgerSpec => ixBurger(pattyOn, cheeseOn, burgerSpec) = | |
addIngredient("No cheese"); | |
let addTopBun: burgerSpec => ixBurger(cheeseOn, topBunOn, burgerSpec) = | |
addIngredient("Top bun"); |
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
module IxFunctor = (IF: Interfaces.IX_FUNCTOR) => {}; | |
module IxApply = (IA: Interfaces.IX_APPLY) => { | |
include IxFunctor(IA); | |
}; | |
module IxApplicative = (IA: Interfaces.IX_APPLICATIVE) => { | |
include IxApply(IA); | |
}; | |
module IxMonad = (IM: Interfaces.IX_MONAD) => { | |
include IxApply(IM); | |
let (>>=:) = IM.ibind; | |
}; |
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
module type IX_FUNCTOR = { | |
type t('x, 'y, 'a); | |
let imap: ('a => 'b, t('x, 'y, 'a)) => t('x, 'y, 'b); | |
}; | |
module type IX_APPLY = { | |
include IX_FUNCTOR; | |
let iapply: (t('x, 'y, 'a => 'b), t('y, 'z, 'a)) => t('x, 'z, 'b); | |
}; | |
module type IX_APPLICATIVE = { | |
include IX_APPLY; | |
let ipure: 'a => t('x, 'x, 'a); | |
}; | |
module type IX_MONAD = { | |
include IX_APPLICATIVE; | |
let ibind: (t('x, 'y, 'a), 'a => t('y, 'z, 'b)) => t('x, 'z, 'b); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment