# Exercises for using abilities

๐Exercise: Implement functions with calls to Ability operations

Given the type signatures below, implement the functions to satisfy the compiler using the request operations of the Ability or functions found in`.base`

``````getWithAbort : a -> Map a b ->{Abort} b
getWithAbort key map = base.todo "implement me!"``````
โจHint: how do I see the request operations of an ability?
โจHint: how do I see the request operations of an ability?
In the UCM, you can enter`view Abort`to see the ability definition. The function signatures after the`where`keyword are the request operations.

Using the`toAbort`function.

``````getWithAbort : a -> Map a b ->{Abort} b
getWithAbort key map = base.todo "implement me!"``````

Pattern matching on`Optional`

``````getWithAbort : a -> Map a b ->{Abort} b
getWithAbort key map = base.todo "implement me!"``````

๐Exercise: Implement functions with Ability operations

``````rangeAverage : Nat ->{Store [Nat]} Float
rangeAverage n = base.todo "implement me"``````

Using the`Store`ability to keep track of a`List`of numbers, write a function which takes in some number`n`of`Nat`as an upper bound of a list from`0`up to (but not including)`n`and returns the average of the final list.

So, given an upper value of`5`,the average produced would be the average of`[0, 1, 2, 3, 4]`,or`2.0`

One possible solution is as follows:

``averageOfRange : Nat ->{Store [Nat]} Float``
``````averageOfRange : Nat ->{Store [Nat]} Float
averageOfRange n =
go = cases
i
| i Nat.== n ->
use Float /
use Nat toFloat
myList = Store.get
listSize = List.size myList
sum =
use Nat +
List.foldLeft (acc element -> element + acc) 0 myList
toFloat sum / toFloat listSize
| otherwise  ->
use List +:
use Nat +
Store.modify (currentList -> i +: currentList)
go (i + 1)
go 0``````

๐Exercise: Apply a handler to a function requiring abilities

Check out the functions in the`base`libraries for operating on`Store`and see if you can apply a handler to the function you wrote previously forThe handler should help you return the`Float`value to check your function.

โจHint: What kind of function am I looking for?
โจHint: What kind of function am I looking for?
You'll want a function whose return type does not require`Store`in curly braces in its final value. The handler should run or "interpret" the program which performs a`Store`ability into another value.

One possible solution is as follows:

``handleAverageOfRange : Float``
``````handleAverageOfRange : Float
handleAverageOfRange = withInitialValue [] '(averageOfRange 5)``````

`withInitialValue`handles a function that requires the`Store`ability by setting the initial state of the`Store`.

๐Exercise: Debug an abilities issue

The following watch expression is failing to typecheck.

``````randomIndex : [Nat] -> '{Random, Abort} Nat
randomIndex list = 'let
n = List.size list
if n === 0 then abort else Random.natIn 0 n

> toOptional! (Random.lcg 7 (randomIndex [1,2,3]))``````

The UCM error is:

``````The 2nd argument to `(<|)`

has type:  Nat
but I expected:  Unit ->{g, Abort} ๐ฉ

142 | randomIndex : [Nat] -> '{Random, Abort} Nat
143 | randomIndex list = 'let
144 |   n = List.size list
145 |   if n === 0 then abort else Random.natIn 0 n
146 |
147 | > toOptional! (Random.lcg 7 (randomIndex [1,2,3]))``````

Why is the error occurring and how might it be corrected?

``````randomIndex : [Nat] -> '{Abort, Random} Nat
`toOptional!`is a function which expects a delayed computation which performs the`Abort`ability. The entire expression will need a`'`symbol in front of the call to`lcg`