Last active
June 11, 2018 04:45
-
-
Save joshuakfarrar/b27afd506e77a0d9f03d4cd4ea9a47b1 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
/* 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