Haskell Journey: Types and Data Structures

Jennifer Takagi
Level Up Coding
Published in
5 min readMar 25, 2021

--

Hey guys, I’ve been a Functional Programming (FP) enthusiast for 2 years so far 🥺. My goal for 2021 is to learn an FP language, so I started to study Haskell… I’ve been studying it for two weeks now and it’s been a funny and challenging journey!

In the hope that I can find more people on this ride and make it at least a little easier for them, I'll be sharing all my discoveries with the highlights of this fantastic programming language on a series of posts to help some new Haskell adventures students.👩🏻‍💻🚀

Photo by Clemens van Lay on Unsplash

If you want to follow my entire journey… I've been:
(1) Learning the concepts based on these books: Haskell an introduction to functional programming and Learn You a Haskell for Great Good! 📚
(2) Taking notes on this Notion document 📝
(3) Coding some exercises on my GitHub repository 🗃

Functional Programming is a programming paradigm, originated in the 1930s. FP is all about functions… Some big concepts are pure (mathematical) functions, immutable data, no/less side-effects, recursions instead loops, high order functions, apply and compose functions. 🤯

FP has a different way to solve problems, mostly because it’s a declarative paradigm, the developer must write what the program has to do and not how!

Haskell is a purely functional programming language, statically typed, with type inference and lazy evaluation.
The first step to code with this language is to install the Haskell Platform on your machine. And to be able to compile your code, you need to use the Glasgow Haskell Compiler (GHC), which’s installed with Haskell.

Commands on GHCi

Here’s a list of some useful commands to use on GHCi:

ghci: to open the interactive terminal:r: to recompile the file :l File.hs: to compile the file (you can omit the extension adding on the very first line of your file: module FileName where) :t Value: to checks the data type

Data Types

On Haskell, every expression’s type is known at compile-time. This means that if you try to sum a string type with some number, your code won’t compile.
Furthermore, the language has type inference, so if you write a string, you don’t need to tell it that it’s a string.

Everything has a type in Haskell. In this post I've covered some basic types just to clarify the types system, because this is an important part on learning this language. The following types are known as “Explicit types”, and they are always denoted with the first letter in a capital case.

  • Char: it represents a character (letters, digits, newlines, tabs, and other symbols): e.g. ‘J’.
  • String or [Char]: it’s just syntactic sugar of a list of Char, so we can use all the list functions on it: e.g: “Jenni”.
  • Bool: it’s a boolean type: e.g: True/False.
  • Int: it represents an integer number, e.g: 1.
  • Integer: it also represents an integer number, but it can be used to represent a big number e.g: 30414093201713378043.
  • Float: it represents a real float number with single precision, e.g: 25.132742.
  • Double: it represents a real float number with double precision, e.g: 25.132741228718344.

We can check the data type using the command “:t Value” on the GHCi, as in the example below. To easily understand what was printed as the response, you can read the notation “::” as “has type of”.

For example: “‘J’ has type of Char”, “‘Jenni’ has type of a list of Char”.

Checking data type on GHCi

Data Structure

Using a data structure is a way to organize, manage and store data… Probably you already used this in any other language. On Haskell there are two types: “list” and “tuple”:

  • List: a “list”, of values that have the same type and a dynamic length: e.g: [1…10]
  • Tuple: in some ways, it’s like a “list”, but the values can have different types but with a fixed-length: e.g: (1, “Hi”)
List and Tuple

The way to read the types follows the same logic that I explained before.
There are a lot of native features (extract value, join lists, push new elements…) and you can check some of them on my Notion document.

🌟 Bonus: List Comprehension

You probably already know this feature from another language, like Python.
List Comprehension can be used to take one or more “lists” and build a new one! It follows the mathematical set-builder notation: set comprehension. The syntax is very simple, Take a look below:

[output function | variable <- input, predicate1, ...predicateN]

Now the formula explained step by step:
(1) the “input” is the original “list”, it supports more than 1;
(2) the “variable” refers to each element from the “input list”;
(3) the “output function” is where we can define the action to each item;
(4) the “predicate” (n) works as a filter, if the variable satisfies it, the output function will be applied and it’ll be returned on the new list.

Code examples to List Comprehension.

Digging Deeper in the examples above:

  • “getVowels”: this function receives a “String” and returns a list with only the characters that are vowels. Using the list comprehension, we can easily iterate each character (remember that “String” is a “list of Char”) and check if it is included on “aeioAEIOU” term — the “isVowel function 😎
  • “sumLists”: this function receives two lists of Integers and sums them. Here we can use list comprehension with more than one list, getting an item of each list and sum them. Passing the lists: [1, 2] and [10, 20, 30], the return is [11, 21, 31, 12, 22, 32] 😱

That’s it! We gave the initial steps on Haskell and I hope now you are more curious about FP and its languages!
If something is not clear, or if there is some mistake on the concepts, fell free to reach me out 📬

See yah in the next post, and stay safe🤟

--

--

Developer focused on technology for troubleshooting! A clean code lover, functional programming enthusiast and passionate about sharing knowledge.