Skip to content

Tutorial 2: Functions and types - init#2

Merged
MarekSuchanek merged 9 commits intomasterfrom
02_functions-types
Mar 2, 2018
Merged

Tutorial 2: Functions and types - init#2
MarekSuchanek merged 9 commits intomasterfrom
02_functions-types

Conversation

@MarekSuchanek
Copy link
Copy Markdown
Contributor

Second tutorial initial version for this semester (B172) is ready, please review and add/change something if necessary...

@MarekSuchanek MarekSuchanek changed the title Tutorial 2: Functions and types, init Tutorial 2: Functions and types - init Feb 19, 2018
Comment thread tutorials/02_functions-types.md Outdated

### Function declaration

Although type can be in most cases inferred automatically by the compiler, it is good practice to write it down at least in case of functions as part of code documentation. Functions can be complicated and by reading its type signature you know immediately what arguments it expects and what it returns.
Copy link
Copy Markdown
Contributor

@roper79 roper79 Mar 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... a good practice ...
... as a part of code ...


myAge :: Age
myAge = Age 20
```
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, type String can be replaced by [Char] (it is a mere synonym), so typechecking is not 'perfect' in this sense. In case of newtype, Age is a different type than Int and compiler will check it.

Comment thread tutorials/02_functions-types.md Outdated
* `Enum` - for enumerations, allows the use of `..` range list syntax such as `[Blue .. Green]`
* `Bounded` - for enumerations or other bounded, `minBound` and `maxBound` as the lowest and highest values that the type can take

As it was said, typeclasses are very important in Haskell and will be covered later on. You will also learn how to make new typeclasses, their instances, etc.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... typeclasses are a very important means of abstraction in Haskell ...

Comment thread tutorials/02_functions-types.md Outdated

## Data types

Haskell has a strong static type system which is one of the things making it so great. As we already saw, every expression in Haskell has some type and the type cannot change during runtime (that is the difference with dynamic typing). As in other programming languages can use predefined data types, get more from some libraries or introduce your own.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... you can ...

x = MyTypeC1 True 10
```

Usually, when there is just one data constructor, the name is the same as of the type constructor (but it is not a rule).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is one another great Haskell feature: Algebraic Data Types (ADT). These are now found in more and more new languages (e.g. 'Rust' and very fresh 'Reason' from Facebook)

Comment thread tutorials/02_functions-types.md Outdated
} deriving Show
```

Now try to create a type `Pet` which also contains `name` and `age`. You will get an error which is logical, you cannot have two functions with the same name! One option is to rename it to `namePerson` and `namePet`, the second is available to you only if you have GHC 8.0.1 or higher and it is with language extension [DuplicateRecordFields](https://downloads.haskell.org/~ghc/master/users-guide/glasgow_exts.html#duplicate-record-fields):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

, however the first option is more common

olderPet pet = pet { age = (age pet + 1) }
```

You can also see that there is a shorthand for updating the value of record - creating new edited record from previous. Now you can try some derived behaviour from typeclasses such as `show`, `read`, or `==`:
Copy link
Copy Markdown
Contributor

@roper79 roper79 Mar 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is one of the weaker parts of Haskell: it actually does NOT have records (as explained, there is just a syntactic sugar upon tuples). Newer languages from the Haskell family PureScript and Elm elaborated on this and introduced 'proper' records.

Comment thread tutorials/02_functions-types.md Outdated
("Hello",7)
```

Good to know is how it actually works and try to implement own tuples.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is, how

Comment thread tutorials/02_functions-types.md Outdated
data List a = Empty | NonEmpty a (List a)
```

That's it! List of type `a` it either `Empty` or `NonEmpty` which means that it has an element and then rest of the list (which can be again `Empty` or `NonEmpty`). Sometimes the following naming is used:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is either

Comment thread tutorials/02_functions-types.md Outdated

### String

String is really nothing but just list of characters `[Char]`. The only difference is that there are more functions for working especially with `String`s - like `putStr`, `lines`, `words` and more (see [Data.String]). For more efficient working with strings is [text] package providing "a time and space-efficient implementation of Unicode text" with [Data.Text] - two variants: Lazy and Strict. Later on, we will get back to this problem which makes a life of Haskell programmer sometimes little bit uneasy.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a list of characters

Comment thread tutorials/02_functions-types.md Outdated

## Simple functions

Enough of types and containers, let's do some functions when this is functional programming course!
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a functional programming...

Comment thread tutorials/02_functions-types.md Outdated

### Basic list functions

Since list is very simple and widely used data structure, it is a good time to learn useful functions to work with lists. You can find a complete list in [Data.List] documentation. Try following examples and examine the type of functions if needed. Also, try to run some unclear cases like `head` of the empty list and see what happens...
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a very simple and widely used

Comment thread tutorials/02_functions-types.md Outdated
False
```

The last one is left fold, there is also right fold (depends on associativity), we will cover this in more detail later while explaining so-called catamorphism. Now you can just see that it is a generalization of `sum`, `and`, `or`, and many others.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

, while

Comment thread tutorials/02_functions-types.md Outdated

The last one is left fold, there is also right fold (depends on associativity), we will cover this in more detail later while explaining so-called catamorphism. Now you can just see that it is a generalization of `sum`, `and`, `or`, and many others.

It is very good practice to try to implement some of these functions to understand them and their complexity. You may worry that using list is always very inefficient, luckily GHC can do some optimizations (although still in some cases you should prefer [Data.Sequence] or other [containers] - we will get back to this during the course).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a very good practice

Comment thread tutorials/02_functions-types.md Outdated
factorial n = n * factorial n-1
```

During any call of subroutine (function, procedure, or other action), it is needed to store information to the [call stack]. Such information consist of where was the call initiated, what was the state and where it should return the value when poping from this stack. For example, with calling `res = factorial 3` call stack could look like this (top on the left):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consists

@MarekSuchanek MarekSuchanek merged commit 7939797 into master Mar 2, 2018
@MarekSuchanek MarekSuchanek deleted the 02_functions-types branch March 2, 2018 07:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants