Recursion conventions in Unison

You do not need to annotate recursive functions with their return type for a program to typecheck.

sum listOfNats = match listOfNats with
   [] -> 0
   head +: tail -> head + (sum tail)

sum [9,8,7,6]

Unison supports tail call elimination. Functions in tail call position (including mutually recursive functions) are evaluated without growing the stack.

Effectful recursion

Recursive code can perform effects too. When your code performs an ability for some kind of computational effect, your function signature should include an ability requirement in curly braces in the return type of the function. See below for an example.

use Nat - == loop : Nat ->{Stream Nat} () loop = cases n | n == 0 -> () | otherwise -> emit n loop (n - 1) Stream.toList do loop 10
โงจ
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

Many of the higher-order functions on data types in the base library are already ability polymorphic. In the signature for List.map, List.map : (a ->{๐•–} b) -> [a] ->{๐•–} [b], the {๐•–} symbol in the lambda argument means that the transformation function a -> b can perform an effect in the process of mapping over each element.