๐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!"
view Abort
to see the ability definition. The function signatures after thewhere
keyword are the request operations.Using theOptional.toAbort
function.
getWithAbort : a -> Map a b ->{Abort} b
getWithAbort key map = toAbort (get key map)
Pattern matching onOptional
getWithAbort : a -> Map a b ->{Abort} b
getWithAbort key map =
match get key map with
Some a -> a
None -> abort
๐Implement functions with Ability operations
rangeAverage : Nat ->{Store [Nat]} Float
rangeAverage n = base.todo "implement me"
Using theStore
ability to keep track of aList
of numbers, write a function which takes in some numbern
ofNat
as an upper bound of a list from0
up to (but not including)n
and returns the average of the final list.
So, given an upper value of5
,the average produced would be the average of[0, 1, 2, 3, 4]
,or2.0
One possible solution is as follows:
averageOfRange : Nat ->{Store [Nat]} Float
averageOfRange : Nat ->{Store [Nat]} Float
averageOfRange n =
use Float / fromNat
use List +:
use Nat + ==
go = cases
i
| i == n ->
myList = Store.get
listSize = List.size myList
sum =
lib.base.data.List.foldLeft
(acc element -> element + acc) 0 myList
fromNat sum / fromNat listSize
| otherwise ->
Store.modify (currentList -> i +: currentList)
go (i + 1)
go 0
๐Apply a handler to a function requiring abilities
Check out the functions in thebase
libraries for operating onStore
and see if you can apply a handler to the function you wrote previously forfinding the average of a range.The handler should help you return theFloat
value to check your function.
One possible solution is as follows:
handleAverageOfRange : Float
handleAverageOfRange = withInitialValue [] '(averageOfRange 5)
withInitialValue
handles a function that requires theStore
ability by setting the initial state of theStore
.
๐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?
One possible solution is as follows:
randomIndex : [Nat] -> '{Abort, Random} Nat
randomIndex list = do
n = List.size list
if n === 0 then abort else base.abilities.Random.natIn 0 n
toOptional! '(lib.base.abilities.Random.lcg 7 (randomIndex [1, 2, 3]))โงจSome 2
toOptional!
is a function which expects a delayed computation which performs theAbort
ability. The entire expression will need a'
symbol in front of the call tolib.base.abilities.Random.lcg