OVO Tech Blog

# A Brief Tour of Haskell for Scala Programmers

## Introduction #### Ed Conolly

I lead the tech teams at OVO. We're building the intelligent energy system of the future.

# A Brief Tour of Haskell for Scala Programmers

Posted by Ed Conolly on .
Featured

# A Brief Tour of Haskell for Scala Programmers

Posted by Ed Conolly on .

Haskell is a purely functional programming language, it's interesting to draw a comparison between Scala and Haskell to see how Scala's hybrid functional / OO approach alters the way it expresses problems. Here's a (very) brief overview of the language and how it compares against Scala.

Haskell and Scala have many similar features as both have clear functional concepts, however Haskell's purely functional nature gives rise to a slightly simpler syntax in certain cases.

## Definitions

Haskell handles all values and data as immutable structures, this means it can lazily evaluate expressions without fear of the underlying information changing.

`val`, `var` and `def` don't have any direct counterparts in Haskell since all evaluation of variables and functions are performed lazyily. In particular `var` is the most removed from Haskell as it declares a mutable value.

Scala

``````val x = 3
val y = 5

def sum(a: Int, b: Int) = a + b

lazy val sentence = "the quick brown fox jumps over the lazy dog"
``````

``````x = 3
y = 5

sum :: Int -> Int -> Int
sum a b = a + b

sentence = "the quick brown fox jumps over the lazy dog"
``````

The most notable differences are the lack of initialisation keyword and the function type signature. In Haskell the type signature is seperate from the implementation, although the compiler will complain if an implemention is missing. All functions are curried in Haskell and the style of the type signature reflects this, sum takes an `Int` and returns a function that takes another `Int`. That function will perform the addition and return the summed value.

When it comes to defining values within functions its common to use `where` and `let` in Haskell. Let's take a quick look.

``````doubleAndAdd :: Int -> Int -> Int
doubleAndAdd a b = doubleA + doubleB
where doubleA = a * 2
doubleB = b * 2
``````

or

``````doubleAndAdd :: Int -> Int -> Int
let doubleA = a * 2
doubleB = b * 2
in doubleA + doubleB
``````

Using `where` both `doubleA` and `doubleB` are scoped to the entire function, the `let` keyword by contrast is an expression in itself and scopes the definitions to everything after `in`.

## Function application

Function application in Haskell is done simply with juxtaposition and without any parentheses, if you do see parentheses it exists purely to handle execution precedence.

Scala

``````double(5)

sum(5, 2)

sum((10 / 2), 2)
``````

``````double 5
sum 5 2
sum (10 / 2) 2
``````

## Anonymous functions, currying, maps and filters

Haskell's maps and filters achieve the same outcome as scala's but are standalone functions opposed to scala collection methods. As a result they read in opposite directions. We can define lambda functions in Haskell using the `\` character.

Scala

``````val foo = List(1, 4, 6, 8, 3, 7, 3, 7, 3, 5)

foo.filter(x => x > 3).map(x => x * 2)
``````

``````foo = [1, 4, 6, 8, 3, 7, 3, 7, 3, 5]

map (\x -> x * 2) (filter (\x -> x > 3) foo)
``````

There are more concise ways we can express the lambdas though in both Scala and Haskell

Scala

``````foo.filter(_ > 3).map(_ * 2)
``````

``````map (*2) \$ filter (>3) foo
``````

In Haskell operators like `*` and `>` are functions that take two arguments. Because functions are curried in Haskell calling those operators with just one argument returns a function we can use nicely in our `map` and `filter` functions. We call this partial application, it's worth remembering it because we'll use it later.

I've also used the `\$` operator here, that's a function application operator and importantly it's right-associative. It's the equivalent of writing something like this with parentheses.

``````map (*2) (filter (>3) foo)
``````

## List comprehensions

We could also express the map and filter operations using a list comprehension.

Scala

``````val foo = List(1, 4, 6, 8, 3, 7, 3, 7, 3, 5)

for (x <- foo if x > 3) yield x*2
``````

``````foo = [1, 4, 6, 8, 3, 7, 3, 7, 3, 5]

[x*2 | x <- foo, x > 3]
``````

List comprehensions in Haskell have the output (or yield) to the left of the pipe `|`, followed by our iterator definition. We can also add predicates into the comprehension to filter out certain values.

Let's look at a slightly more indepth example. What about finding the length of the sides of a right angle triangle with total perimeter of 24?

Scala

``````for {
x <- 1 to 10
y <- 1 to x
z <- 1 to y
if Math.pow(z, 2) + Math.pow(y, 2) == Math.pow(x, 2)
if x + y + z == 24
} yield (x, y, z)
``````

``````[(x, y, z) | x <- [1..10], y <- [1..x], z <- [1..y], z^2 + y^2 == x^2, x + y + z == 24]
``````

## Pattern matching

Haskell offers pattern matching quite similar to Scala's, but offers some nice syntatic sugar for pattern matching on function arguments. Let's start by looking at a normal pattern match

Scala

``````foo match {
case Nil => "Empty List"
case xs => "The list is " + xs.length + " long"
}
``````

``````case foo of [] -> "Empty list"
xs -> "The list is " ++ show (length xs) ++ " long"
``````

Its worth noting that strings are concatonated just like lists in Haskell using the `++` operator. We also have to explicitly convert `length xs` to a string using the `show` function.

The above examples seem pretty similar, but when we start looking at pattern matching on function arguments Haskell starts doing things a little differently.

Scala

``````def sumList(a: List[Int]): Int = a match {
case Nil => 0
case (x::xs) => x + sumList(xs)
}

//or with an anonymous function

val sumList2: (List[Int]) => Int = {
case Nil => 0
case (x::xs) => x + sumList2(xs)
}
``````

``````sumList :: [Int] -> Int
sumList [] = 0
sumList (x:xs) = x + sumList xs
``````

Haskell's implementation is very clear and concise IMO. It's also possible to add guards to the pattern match using the `|` operator in haskell.

Scala

``````def sumLargeOnly(a: List[Int]): Int = a match {
case Nil => 0
case (x::xs) if x > 10 => x + sumList(xs)
case (x::xs) => sumList(xs)
}
``````

``````sumLargeOnly :: [Int] -> Int
sumLargeOnly [] = 0
sumLargeOnly (x:xs)
| x > 10 = x + sumList xs
| otherwise = sumList xs
``````

## Custom data types

Since Haskell is purely functional data structures are just representations of data, and do not contain methods like Scala's classes, case classes and objects. It has however become quite common for scala developers to use `case class` as a way to represent data structures with no methods, and since case classes are available for pattern matching they're probably the best comparison to Haskell's `data`.

Scala

``````case class Car(make: String, model: String, year: Int)

lazy val myCar = Car("Citroen", "C4", 2006)

// or with arguments specified

lazy val yourCar = Car(model="Mustang", make="Ford", year=1969)
``````

``````data Car = Car { make :: String
, model :: String
, year :: Int
}

myCar = Car "Citroen" "C4" 2006

// or with arguments specified

yourCar = Car {model="Mustang", make="Ford", year=1969}
``````

It's also possible to data types without naming the arguments, kind of like an inbetween of a tuple and a case class.

``````data Point = Point Float Float

center = Point 0 0
``````

Here we're defining the data structure `Point` as something which is created from 2 `Float` arguments.

Pattern matching with these data structures is probably as you'd expect

Scala

``````myCar match {
case Car("Citroen", _, _) => "Your car is a Citroen"
case _ => "Support the French, buy a Citroen!"
}
``````

``````case myCar of (Car "Citroen" _ _) -> "Your Car is a Citroen"
_ -> "Support the French, buy a Citroen!"

``````

These data structures in Haskell are really just functions, so we get all of the benefits of functions in Haskell. Here we use partial application to produce a list of Citroen's from 2000 - 2007.

``````map (Car "Citroen" "C4") [2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007] 