Values in Unison are not, by default, lazily evaluated. But it's common to want to express that a value or calculation should be delayed until it's absolutely needed.
For example the termlongText
in the following snippet is evaluated strictly:
longText : Text
longText = "๐ต Imagine infinite monkeys on infinite typewriters ๐โฆ"
coinflip : Boolean -> Text
coinflip bool = if bool then longText else "Hi"
But you might not actually need to evaluatelongText
--thereare circumstances where the calculation of a value might be very expensive or could introduce surprising behavior if runeagerly.
One way you might solve for this is to create a "thunk": a function with no arguments which returns the desired value or computation when it's called.
longText : () -> Text
longText _ = "๐ต Imagine infinite monkeys on infinite typewriters ๐โฆ"
Because this is a common pattern, Unison provides the single quote,'
,as syntactic sugar for representing a function with the form() -> a
.
We can rewrite the type() -> Text
as just'Text
.
Just as Unison provides syntax for representing delayed computations in a type signature, there are a few ways to delay an expression in Unison.
When we want to run the thunk, we could call the value with()
to represent "I'm calling this with zero arguments", but Unison also provides syntactic sugar for "forcing" or calling a thunk with the!
symbol.
Calling our functionlongText
looks like:
To review: single quote,'
,an underscore_
,or thedo
keyword introduce athunkand the bang symbol,!
,executes it, but what if we want to callcoinflip
with an argumenttrue
and then return the result of that function application in a thunk? Our final desired return type is'Text
.To do that, we have to surround the function application forcoinflip true
in parentheses before prepending the single quote symbol.