Skip to content

arecvlohe/reasonml-cheat-sheet

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 

Repository files navigation

ReasonML Cheat Sheet

ReasonML is a functional, strongly typed, programming language. It looks like JavaScript and compiles to JavaScript/Node as well as other languages. It is a dialect of OCaml and is compiled using BuckleScript. Therefore, you can use OCaml and BuckleScript APIs when using Reason.

Try it Out

If you want a more interactive example of ReasonML's language features, check out this link to the ReasonML REPL on their homepage: 👉 Click here 👈.

Comments

/* This is a comment whether single or multi-line */

Types

  1. Types are inferred. This means you don't have to declare types but you can if you want.
  2. Type coverage is 100%. Because types are inferred it means coverage is everywhere.
  3. Type system is sound. Compile and forget.

Types: list, array, string, char, bool, int, float, unit, option, etc.

Generics

Generics are created by putting a ' in front of an arbitrary variable name. However, it is most common to see single letters used.

let length: array('a) => int;

Generics allow you to use a function in a more generic way. In the case of length, it's a function which takes an array of any type, 'a, and returns an int. In this instance, 'a can be a string, an int, or a record. What it enforces is that the array contains only that type. It can either be array(int) or array(string) but not both.

Phantom Types

"A phantom type is a parametrised type whose parameters do not all appear on the right-hand side of its definition..." - Haskell Wiki, PhantomType

type formData('a) = string;

Here formData is a phantom type as the 'a parameter only appears on the left side.

References

Abstract Types

An abstract type is a type without a concrete definition.

module type Person = {
  type details;
  
  let person: details;
  let make: unit => details;
  let greet: details => string;
} 

From the example above, the module declares the details type but leaves it to the module to define its implementation.

module Person: Person = {
  type details = { name: string, age: int };
  
  let person = { name: "Adam", age: 31};
  let make = () => person;
  let greet = (details) => "Hello. My name is " ++ details.name ++ " and I am " ++ string_of_int(details.age) ++ " years old.";
}

let adam = Person.make();
let greet = Person.greet(adam);

References

List

Lists are created with square brackets:

let list: list(int) = [1, 2]

Spread

let list1 = [1, 2, 3];
let list2 = [0, ...list1];

Js.log(list2); /* [0, 1, 2, 3] */

* Can only use the spread operator once within a list

Rest

let list: list(int) = [1, 2, 3, 4];

let pm = (list): string => {
  switch(list) {
    | [] => "Empty"
    | [head, ...tail] => {j|I only want $head|j}
  }
};

Js.log(pm(list)); /* I only want 1 */

Array

Arrays are created with square brackets and pipes:

let arr: array(string) = [|"a", "b"|]

String

Strings are created with double quotes:

let str: string = "Yeah, to you it's Thanksgiving; to me it's Thursday"

Strings are concatenated with double plus signs:

let stringConcat: string = "Yo Adrian, " ++ "I did it!"

String interpolation comes with help from BuckleScript:

let rocky: string = "Rocky"
let mickey: string = "Mickey"

let scene: string = {j|$mickey makes $rocky chase chickens to get in shape.|j}

Char

Characters are created using single quotes:

let char: char = 'a';

Js.log(char); /* 97 */

Functions

Named

let someFunction = () => "someFunction";

Anonymous

let someFunction = () => {
  () => {
    "someAnonFunction"
  }
};

Js.log(someFunction()()); /* "someAnonFunction" */

Labeled Arguments

let labeledArgs = (~arg1, ~arg2) => {
  arg1 ++ arg2
};

Js.log(labeledArgs(~arg1="Some ", ~arg2="labeled args.")); /* "Some labeled args." */

Labeled As

let labeledArgs = (~arg1 as one, ~arg2 as two) => {
  one ++ two
};

Js.log(labeledArgs(~arg1="Some ", ~arg2="labeled args.")); /* "Some labeled args." */

Default and Optional Arguments

let labeledArgs = (~arg1="Some ", ~arg2=?, ()) =>
  switch (arg2) {
  | Some(arg) => arg1 ++ arg
  | None => arg1 ++ "labeled args."
  };

let res = labeledArgs(~arg2=?Some("labeled args"), ());

Js.log(res); /* Some labeled args. */

Partial Application

let labeledArgs = (~arg1 as one, ~arg2 as two) => {
  one ++ two
};

let firstArg = labeledArgs(~arg1="Some ");

let secondArg = firstArg(~arg2="labeled args.");

Js.log(secondArg); /* "Some labeled args." */

* Doesn't matter which order you pass the labeled argument

Destructuring

List

let [a, b]: list(int) = [1, 2];

Array

let [|a, b|]: array(int) = [|1 , 2|];

Tuple

let (a, b): (int, int) = (1, 2);

Pattern Matching

Use the switch to pattern match against values:

switch (value) {
  | 1 => "one"
  | _ => "Everything else"
};

Literal

switch (1) {
  | 1 => "one"
  | _ => "Everything else"
};

Option

switch (option) {
  | Some(option) => option
  | None => None
};

Destructuring

let arr: array(int) = [|1, 2, 3|];

let matchArr: array(int) => int = arr => {
  switch (arr) {
    | [|a, b, _|] => a + b
    | [|a, b|] => a
    | [|a|] => 0
    | [||] => -1
    | _ => 0
  };
};

Js.log(matchArr(arr)); /* 3 */

Guards

let arr = [|1, 2, 3|];

let matchArr: array(int) => int = (arr) =>
  switch arr {
  | [|a, b, _|] when a < 2 => a + b
  | [|a, _, _|] when a > 2 => a
  | [|a|] => 0
  | [||] => (-1)
  | _ => 0
  };

Js.log(matchArr(arr)); /* 3 */

Types

Literal

Record

type person = {
  firstName: string,
  lastName: string
};

let listOfPerson: list(person) = [{ firstName: "Rocky", lastName: "Balboa" }];

Closed Object

type obj = {
  .
  color: string,
};

let car: obj = {
  pub color = "Red"
};

Js.log(car#color); /* "Red" */

* Objects in Reason are like constructors in JS

Open Object

type obj('a) = {
  ..
  color: string,
} as 'a;

let car: obj({. color: string, isRed: unit => bool }) = {
  pub color = "Red";
  pub isRed = () => this#getColor() == "Red";
  pri getColor = () => this#color;
};

Js.log(car#isRed()); /* true */

JavaScript Object

type person = {
 .
 "name": string,
 [@bs.meth] "greet": unit => unit,
};

let printPerson = (p:person) => {
  Js.log(p##name);
  p##greet();
}

Tuple

type message: (int, string) = (200, "Success");

Tagged Union

type person =
  | Rocky
  | Mickey
  | Adrian;

let matchPerson: person => string = (who: person) =>
  switch who {
  | Rocky => "Rocky"
  | Mickey => "Mickey"
  | Adrian => "Adrian"
  };

Js.log(matchPerson(Rocky)); /* "Rocky" */

Operators

Symbol Meaning
+ integer addition
+. float addition
- integer subtraction
-. float subtraction
* integer multiplication
*. float mulitplication
/ integer division
/. float division
** exponentation
|> pipe / reverse application operator
@@ application operator
~+ unary addition integer
~+. unary addition float
~- unary negation integer
~-. unary negation float
++ string concatenation
@ list concatenation
-> pipe first

Helpful BuckleScript/OCaml Functions

Function Meaning
Js.log Logs value to console
Js.Float.isNaN Checks to see if value is NaN
string_of_int Convert integer into string
string_of_float Convert float to string

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •