Skip to content

Instantly share code, notes, and snippets.

// A simple sum type that has two options
sealed trait Option[A]
// A value of some type 'A' (product type with a single field)
case class Some[A](value: A) extends Option[A]
// Type constructor that represents absence of a value
case class None[A]() extends Option[A]
// Instead of throwing an exception or crashing the function will
object MyProgram extends App {
unsafeRun( // <-- This guy takes your pure program
// and actually runs it
printResult( // --
doSomethingElse( // |
doThat( // |
doThis() // | This is your 'pure' part, nothing happened yet
) // |
) // |
) // --
object MyProgram extends App {
doThis()
doThat()
doSomethingElse()
printResult()
}
-- Add 1 to every item in the list
map (+1) [1,2,3,4,5] -- [2,3,4,5,6]
-- Sum all the values
foldl' (+) 0 [1,2,3,4,5] -- 15
-- Multiply each number by 2, convert to string and
-- produce a total string appending the results together
foldl' (\acc n -> acc ++ show (n * 2)) "" [1,2,3,4,5] -- "246810"
// Pass a function to transform every item in the list
List(1,2,3,4,5).map(n => n + 1) // List(2,3,4,5,6)
// Or shorter syntax
List(1,2,3,4,5).map(_ * 2) // List(2,4,6,8,10)
// Fold example. Sum all the values in a list
List(1,2,3,4,5).fold(0)((l, r) => l + r) // 15
// Multiply each number by 2, convert to string and
-- Similar to Scala version, List is just a sum type with two options
-- [] is a type constructor for an empty list
mySum :: [Int] -> Int
mySum [] = 0
mySum (x : xs) = x + (mySum xs)
-- We will step through the list building a sum expression until we hit
-- the empty list case which returns 0. That will close the loop and
-- the built up expression will be summed up
// 'List' is defined as a sum type so we can use pattern matching.
// There are two type constructors we need to check: one for empty list and
// one for head and tail:
def sum(lst: List[Int]): Int = lst match {
case Nil => 0 // Nil is a type constructor for an empty list
case x :: xs => x + sum(xs) // x :: xs looks weird but it's actually just
// a product type named '::' and can be rewritten as
// case ::(x, xs) => ...
// Scala allows infix operators for type constructors
// so it's possible to say 'case x :: xs'
isPositive :: Int -> Bool
isPositive number = undefined -- compiles but throws exception when called
-- Or
isPositive number = error "meh" -- same
// Just an example, don't do this at home
def isPositive(number: Int): Boolean = {
if (number == 0)
throw new Exception("meh") // Partial (non total)
else {
println("Calling isPositive!") // Impure (writing to std out is a side effect)
if (System.currentTimeMillis() % 2 == 0) // Non deterministic
number > 0
else
data Shape
= Circle { radius :: Double }
| Rectangle { width :: Double
, height :: Double }
-- In haskell different options of a sum type can
-- be handled with different 'functions'
area :: Shape -> Double
area (Circle r) = pi * r * r
area (Rectangle w h) = w * h -- width and height are captured in 'w' and 'h'