Skip to content

Instantly share code, notes, and snippets.

@joshuakfarrar
Last active June 11, 2018 04:45
Show Gist options
  • Save joshuakfarrar/b27afd506e77a0d9f03d4cd4ea9a47b1 to your computer and use it in GitHub Desktop.
Save joshuakfarrar/b27afd506e77a0d9f03d4cd4ea9a47b1 to your computer and use it in GitHub Desktop.
/* interop */
[@bs.val] [@bs.scope "Math"] external random : unit => float = "random";
[@bs.val] [@bs.scope "Math"] external floor : float => int = "floor";
let random = (max: float): int => {
floor(random() *. max);
};
let x = (n: int): option('float) => {
switch (n) {
| 0 => None
| _ => Some(float_of_int(100/n))
}
};
/* functorForFloat allows us to lift random */
/* how can i abstract over this so the functor does not have to care about the types of f or fa? */
let maybeLog = (o: option('int)) => {
switch (o) {
| None => Js.log("nope")
| Some(x) => Js.log({j|x: $x|j})
}
};
let functorForOption = (f: float => int, fa: option('float)): option('int) => {
switch(fa) {
| Some(a) => Some(f(a))
| _ => None
}
};
let y: option('int) = functorForOption(random, x(20));
maybeLog(y);
/* using Belt, the stdlib */
let z: option('int) = Belt.Option.map(x(20))(random);
maybeLog(z);
/* polymorphic variants and type constraints */
type rgb = [`Red | `Green | `Blue]
type color = [rgb | `Yellow | `Orange]
/* this function does not accept colors */
let name = (x: [> rgb]) =>
switch (x) {
| `Red => "red"
| `Green => "green"
| `Blue => "blue"
};
/* this function does not accept rbgs */
let subname = (x: [< color]) =>
switch (x) {
| `Yellow => "yellow"
| `Orange => "orange"
};
Js.log(name(`Red));
Js.log(subname(`Orange));
/* "functors", not to be confused with Functor, a type which is mappable */
module Derp = {
type a=string;
type b=unit;
let map = (d: option(a), f: a => b): option(b) =>
switch (d) {
| Some(a) => Some(f(a))
| None => None
};
};
/* lambdas */
Derp.map(x, (y => Js.log(y)));
/* objects; for when it walks like a duck */
type entity('a) = {
..
} as 'a;
let player: entity({. age: int}) = {
pub age = 5;
};
let kraken: entity({. age: int}) = {
pub age = 5000;
};
let getAge = (e: entity({. age: int})) => e#age;
Js.log(getAge(player));
Js.log(getAge(kraken));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment