Webpage of the Compositional Systems and Methods group at TalTech.

- Write a function
`running_sum : IO Nat`

that descricbes a computation in which the user is repeatedly prompted to enter a number (a`Nat`

) until they enter a string that does not represent a number, at which point the sum of all numbers entered is returned. For example:`> :exec running_sum > enter a number: > 5 (user input) > enter a number: > 42 (user input) > enter a number: > 16 (user input) > enter a number: > I'd rather not (user input) > 63 (final return value)`

If the user enters no numbers, the computation should return

`0`

. - Write a function
`in_sequence : List (IO ()) -> IO ()`

which, given a list of descriptions of computations that don’t return anything, describes the computation in which each of the input computations is carried out in sequence. For example:`> :exec (in_sequence [ putStrLn "hello", putStrLn "world"]) > hello > world`

- Write a function
`collect_results : List (IO a) -> IO (List a)`

which, given a list of descriptions of computations that return something of type`a`

, describes the computation in which each of the input computations is carried out in sequence, and returns the list of results obtained. For example:`> :exec (collect_results [ getLine, pure "there", getLine ]) > hello (user input) > computer (user input) > ["hello", "there", "computer"] (final return value)`

- Write a function
`once_definitely : String -> String -> (String -> Maybe a) -> IO a`

such that, for example:`> :exec (once_definitely "enter a Nat: " "That's not a Nat! Try again!" parsePositive) > Enter a Nat: > I don't want to! (user input) > That's not a Nat! Try again! > Enter a Nat: > You can't make me! (user input) > That's not a Nat! Try again! > Enter a Nat: > Please, let me go. (user input) > That's not a Nat! Try again! > Enter a Nat: > 5 (user input) > 5 (final return value)`

The idea being that in

`once_definitely prompt err_msg foo`

,`prompt`

is the prompt we display to the user,`foo : String -> Maybe a`

tries to parse the user’s string to obtain an`a`

. If parsing succeeds, we return the value thus obtained. If parsing fails, we display our error message`err_msg`

, and try again. -
Say that a Nat is palindromic in case reversing its base 10 digits yields the same Nat. For example

`8`

,`0`

, and`131`

are palindromic, but`52`

,`10`

, and`466`

are not. Write a function`ensure_palindrome : Nat -> Maybe Nat`

such that`ensure_palindrome n`

is`Nothing`

if the`n`

is not palindromic, and is`Just n`

if`n`

is palindromic. Note that reversing the digits of`10`

yields`01 = 1`

, and so on for any number of trailing zeroes. -
This question has three parts.

A: Write two more functions

`ensure_odd : Nat -> Maybe Nat`

and`ensure_prime : Nat -> Maybe Nat`

which ensure that the input is odd and prime respectively (this should be easy now!).B: Suppose have a list of properties we would like to ensure that a

`Nat`

satisfies, given as functions`Nat -> Maybe Nat`

as above. Write a function that collects the list of properties into a single property`Nat -> Maybe Nat`

that holds in case all the properties in our list of properties hold. That is, write a function`unify_properties : List (Nat -> Maybe Nat) -> (Nat -> Maybe Nat)`

.C: Use

`unify_properties`

to compute the sum the first 10`Nat`

s that are odd, prime, and palindromic.