A few exercises relevant to values and functions.

๐Exercise: Understand parentheses in type signatures

`List.zipWith`

is a function which takes in two lists and a function which operates on the elements in both lists sequentially until the end of one of the lists is reached.

A mysterious parenthesis blight has wiped away the necessary parentheses to communicate this.

`blightedZipWith: a -> b -> c -> [a] -> [b] -> [c]`

Where should the parentheses in the type signature go? Where should the implied parentheses go for this type signature?

`threeArgumentFunction : Nat -> Text -> Boolean -> Nat`

Is analogous to

`threeArgumentFunction: Nat -> (Text -> (Boolean -> Nat))`

It's easy to conflate the order of function**application**(the order in which a function is called) with the order of its type notation. Here we're looking for a description of where to draw the implied and actual parentheses for how the function arrow`->`

works in a type signature.

The required parentheses are as follows:

`zipWith: (a -> b -> c) -> [a] -> [b] -> [c]`

The first argument to`List.zipWith`

is a function with two arguments`a`

and`b`

.Lists`[a]`

and`[b]`

are the two lists being zipped, and`[c]`

is the return type of the over all function.

Adding the implied parentheses for the type signature yields:

`zipWith: ((a -> (b -> c)) -> ([a] -> ([b] -> [c])))`

๐Exercise: Understand parentheses when calling functions

A similar parenthesis blight has afflicted the site where we're calling our function. Add both the implied and necessary parentheses to the following code

```
use Nat
listA = [1,2,3,4,5]
listB = [2,4,6,8,10]
fixMe = List.zipWith a -> b -> a + b listA listB
```

The required parentheses are as follows:

```
use Nat
listA = [1,2,3,4,5]
listB = [2,4,6,8,10]
fixMe = List.zipWith (a -> b -> a + b) listA listB
```

Adding the implied parentheses for the order in which function application occurs:

```
use Nat
listA = [1,2,3,4,5]
listB = [2,4,6,8,10]
fixMe = ((List.zipWith (a -> b -> a + b) listA) listB)
```

๐Exercise: Determine a type signature for a function from how it's called

Write the signature for`lib.base.data.List.foldLeft`

given the following information:

An example of how`foldLeft`

is called is

You can read about what`lib.base.data.List.foldLeft`

does by reading the docs linked here:`base.data.List.foldLeft.doc`

or by entering`docs List.foldLeft`

in the UCM.

`Text.size`

to transform`Text`

into a number, and then adds the length of each text element together, but`lib.base.data.List.foldLeft`

should be polymorphic--that is, it should not care if it is operating on is a List of Text, or a List of Char or a List of Boolean.The first argument to`lib.base.data.List.foldLeft`

is a function with two arguments, the first is the value that is being accumulated as the fold function is operating on each element on the list, the second corresponds to the element of the list.

The second argument to the`lib.base.data.List.foldLeft`

function is the value that should be applied when the higher order function encounters the end of the list.

The third argument to List.foldLeft is the list being folded over.

Note, the actual signature of`lib.base.data.List.foldLeft`

contains a parameter in curly braces,`{e}`

.`lib.base.data.List.foldLeft`

isability polymorphic,meaning that the step function provided to it can perform effects. We'll be covering those later in our section on Abilities.

`lib.base.data.List.foldLeft : (b ->{๐} a ->{๐} b) -> b -> [a] ->{๐} b`

๐Exercise: Debug a Unison function which fails to typecheck

```
brokenFactorial : Nat -> Nat
brokenFactorial n =
use Universal Nat
if n === 0 then 1 else n * brokenFactorial decrement n
```

We'll cover the`use`

keyword later, we're using it above to disambiguate a few function names.

Something is wrong with this function. It does not typecheck, and the UCM prints out the following error. See if you can fix it.

```
This looks like a function call, but with a Nat where the function should be. Are you missing an operator?
5 | if n === 0 then 1 else n * brokenFactorial decrement n
```

`else`

clause?Due to the order of function application, we need to surround the call to`Nat.decrement`

with parentheses.

```
use Nat *
factorial : Nat -> Nat
factorial n = if n === 0 then 1 else n * factorial (Nat.decrement n)
factorial 3โงจ6
```

๐Exercise: Write your own Unison function

Write a function which, when given a list, removes every other element from the list. So,`["a", "b", "c", "d"]`

becomes`["a", "c"]`

.The function should work on a list of any type.

```
removeEveryOther : [a] -> [a]
removeEveryOther as = base.todo "Implement here"
```

Some tests to validate this function are copied below, but they're also available under the`ex5.tests`

namespace.

```
test> test1 = check(removeEveryOther ["a","b","c","d","e"] test.=== ["a", "c", "e"])
test> test2 = check(removeEveryOther [1] test.=== [1])
test> test3 = check(removeEveryOther [] test.=== [])
```

`lib.base.data.List.indexed`

for a simple way to pair each element in the list with its index.`Nat.mod`

.One possible answer:

`removeEveryOther : [a] -> [a]`

```
removeEveryOther : [a] -> [a]
removeEveryOther ns =
iList = lib.base.data.List.indexed ns
tups =
lib.base.data.List.filter
(tup -> Nat.mod (at2 tup) 2 === 0) iList
lib.base.data.List.map (tup -> at1 tup) tups
```