Prelude
The Prelude is FreeST’s standard library. Its types and functions are in scope in every program, with no import required — everything listed on this page is available by default.
The terse arithmetic, logic and text operators are collected into tables below; the more involved combinators, channel operations and stream types each get their own entry with a description and, where useful, a worked example.
Table of contents
Arithmetic
Integer arithmetic
| Function | Type |
|---|---|
(+) | Int -> Int -> Int |
(-) | Int -> Int -> Int |
(*) | Int -> Int -> Int |
(/) | Int -> Int -> Int |
div | Int -> Int -> Int |
(^) | Int -> Int -> Int |
mod | Int -> Int -> Int |
rem | Int -> Int -> Int |
max | Int -> Int -> Int |
min | Int -> Int -> Int |
quot | Int -> Int -> Int |
gcd | Int -> Int -> Int |
lcm | Int -> Int -> Int |
subtract | Int -> Int -> Int |
succ | Int -> Int |
pred | Int -> Int |
abs | Int -> Int |
negate | Int -> Int |
even | Int -> Bool |
odd | Int -> Bool |
Integer comparison
| Function | Type |
|---|---|
(==) | Int -> Int -> Bool |
(/=) | Int -> Int -> Bool |
(<) | Int -> Int -> Bool |
(>) | Int -> Int -> Bool |
(<=) | Int -> Int -> Bool |
(>=) | Int -> Int -> Bool |
Floating-point arithmetic and comparison
| Function | Type |
|---|---|
(+.) | Float -> Float -> Float |
(-.) | Float -> Float -> Float |
(*.) | Float -> Float -> Float |
(/.) | Float -> Float -> Float |
(>.) | Float -> Float -> Float |
(<.) | Float -> Float -> Float |
(>=.) | Float -> Float -> Float |
(<=.) | Float -> Float -> Float |
absF | Float -> Float |
negateF | Float -> Float |
maxF | Float -> Float -> Float |
minF | Float -> Float -> Float |
recip | Float -> Float |
Floating-point functions
| Function | Type |
|---|---|
pi | Float |
exp | Float -> Float |
log | Float -> Float |
sqrt | Float -> Float |
(**) | Float -> Float -> Float |
logBase | Float -> Float -> Float |
sin | Float -> Float |
cos | Float -> Float |
tan | Float -> Float |
asin | Float -> Float |
acos | Float -> Float |
atan | Float -> Float |
sinh | Float -> Float |
cosh | Float -> Float |
tanh | Float -> Float |
log1p | Float -> Float |
expm1 | Float -> Float |
log1pexp | Float -> Float |
log1mexp | Float -> Float |
Numeric conversions
| Function | Type |
|---|---|
truncate | Float -> Int |
round | Float -> Int |
ceiling | Float -> Int |
floor | Float -> Int |
fromInteger | Int -> Float |
Booleans, characters and strings
Booleans
| Function | Type |
|---|---|
(&&) | Bool -> Bool -> Bool |
(||) | Bool -> Bool -> Bool |
Characters
| Function | Type |
|---|---|
ord | Char -> Int |
chr | Int -> Char |
Strings
| Function | Type |
|---|---|
(^^) | String -> String -> String |
Showing and reading values
| Function | Type |
|---|---|
show | forall a:*T . a -> String |
readBool | String -> Bool |
readInt | String -> Int |
readChar | String -> Char |
General-purpose functions
Bool
data Bool = True | False
not
not : Bool -> Bool
Boolean complement
id
id : forall a:*T . a -> a
The identity function. Will return the exact same value.
id 5 -- 5
id "Hello" -- "Hello"
flip
flip : forall a:*T b:*T c:*T . (a -> b -> c) -> b -> a -> c
Swaps the order of parameters to a function
-- | Check if the integer is positive and the boolean is true
test : Int -> Bool -> Bool
test i b = i > 0 && b
-- | Flipped version of function 'test'
flippedTest : Bool -> Int -> Bool
flippedTest = flip @Int @Bool @Bool test
($)
($) : forall a:*T b:*T. (a -> b) -> a -> b
Application operator. Takes a function and an argument, and applies the first to the latter. This operator has low right-associative binding precedence, allowing parentheses to be omitted in certain situations. For example:
f $ g $ h x = f (g (h x))
(|>)
(|>) : forall a:*T b:*T. a -> (a -> b) -> b
Reverse application operator. Provides notational convenience, especially when chaining channel operations. For example:
f : !Int ; !Bool ; Close -> ()
f c = c |> send 5 |> send True |> close
Its binding precedence is higher than $.
(;)
(;) : forall a:*T b:*T . a -> b -> b
Sequential composition. Takes two expressions, evaluates the former and discards the result, then evaluates the latter. For example:
3 ; 4
evaluates to 4. Its binding precedence is rather low.
until
until : forall a:*T . (a -> Bool) -> (a -> a) -> a -> a
Applies the function passed as the second argument to the third one and uses the predicate in the first argument to evaluate the result, if it comes as True it returns it, otherwise, it continues to apply the function on previous results until the predicate evaluates to True.
-- | First base 2 power greater than a given limit
firstPowerGreaterThan : Int -> Int
firstPowerGreaterThan limit = until @Int (> limit) (*2) 1
curry
curry : forall a:*T b:*T c:*T . ((a, b) -> c) -> a -> b -> c
Converts a function that receives a pair into a function that receives its arguments one at a time.
-- | Sums the elements of a pair of integers
sumPair : (Int, Int) -> Int
sumPair p = let (x, y) = p in x + y
-- | Regular sum
sum : Int -> Int -> Int
sum = curry @Int @Int @Int sumPair
uncurry
uncurry : forall a:*T b:*T c:*T . (a -> b -> c) -> ((a, b) -> c)
Converts a function that receives its arguments one at a time into a function on pairs.
-- | Sums the elements of a pair of integers
sumPair : (Int, Int) -> Int
sumPair = uncurry @Int @Int @Int (+)
swap
swap : forall a:*T b:*T . (a, b) -> (b, a)
Swaps the components of a pair. The expression swap (1, True) evaluates to (True, 1).
fix
fix : forall a:*T . ((a -> a) -> (a -> a)) -> (a -> a)
Fixed-point Z combinator
fst
fst : forall a:1T b:*T . (a, b) -> a
Extracts the first element from a pair, discarding the second.
snd
snd : forall a:*T b:1T . (a, b) -> b
Extracts the second element from a pair, discarding the first.
Partial functions
| Function | Type |
|---|---|
error | forall a:*T . String -> a |
undefined | forall a:*T . a |
Channels and concurrency
new
new : forall a:1A . () -> (a, dualof a)
Creates two endpoints of a channels of the given type.
send
send : forall a:1T . a -> forall b:1S . !a ; b 1-> b
Sends a value on a channel. Returns the continuation channel
receive
receive : forall a:1T b:1S . ?a ; b -> (a, b)
Receives a value on a channel. Returns the received value and the continuation channel.
close
close : Close -> ()
Closes a channel.
wait
wait : Wait -> ()
Waits for a channel to be closed.
fork
fork : forall a:*T. (() 1-> a) -> ()
Diverge
type Diverge = ()
A mark for functions that do not terminate
sink
sink : forall a:*T . a -> ()
Discards an unrestricted value
repeat
repeat : forall a:*T . Int -> (() -> a) -> ()
Executes a thunk n times, sequentially
main : ()
main =
-- print "Hello!" 5 times sequentially
repeat @() 5 (\_:() -> putStrLn "Hello!")
parallel
parallel : forall a:*T . Int -> (() -> a) -> ()
Forks n identical threads. Works the same as a repeat call but in parallel instead of sequentially.
main : ()
main =
-- print "Hello!" 5 times in parallel
parallel @() 5 (\_:() -> putStrLn "Hello!")
receiveAndWait
receiveAndWait : forall a:1T . ?a ; Wait -> a
Receives a value from a linear channel and applies a function to it. Discards the result and returns the continuation channel.
main : ()
main =
-- create channel endpoints
let (c, s) = new @(?String ; Wait) () in
-- fork a thread that prints the received value (and closes the channel)
fork (\_:() 1-> c |> readApply @String @End putStrLn |> wait);
-- send a string through the channel (and close it)
s |> send "Hello!" |> close
Receives a value from a channel that continues to Wait, closes the continuation and returns the value.
main : ()
main =
-- create channel endpoints
let (c, s) = new @(?String ; Wait) () in
-- fork a thread that prints the received value (and closes the channel)
fork (\_:() 1-> c |> receiveAndWait @String |> putStrLn);
-- send a string through the channel (and close it)
s |> send "Hello!" |> close
receiveAndClose
receiveAndClose : forall a:1T . ?a ; Close -> a
As in receiveAndWait only that the type is Close and the function closes the channel rather the waiting for the channel to be closed.
sendAndWait
sendAndWait : forall a:1T . a -> !a ; Wait 1-> ()
Sends a value on a given channel and then waits for the channel to be closed. Returns ().
sendAndClose
sendAndClose : forall a:1T . a -> !a ; Close 1-> ()
Sends a value on a given channel and then closes the channel. Returns ().
receive_
receive_ : forall a:1T . *?a -> a
Receives a value from a star channel. Unrestricted version of receive.
send_
send_ : forall a:1T . a -> *!a 1-> ()
Sends a value on a star channel. Unrestricted version of send.
accept
accept : forall a:1A . *!a -> dualof a
Session initiation. Accepts a request for a linear session on a shared channel. The requester uses a conventional receive to obtain the channel end.
forkWith
forkWith : forall a:1A b . (dualof a 1-> b) -> a
Creates a new child process and a channel through which it can communicate with its parent process. Returns the channel endpoint.
main : ()
main =
-- fork a thread that receives a string and prints
let c = forkWith @(!String ; Wait) @() (\s:(?String ; End) 1-> s |> receiveAndWait @String |> putStrLn) in
-- send the string to be printed
c |> send "Hello!" |> wait
runServer
runServer : forall a:1A b:*T . (b -> dualof a 1-> b) -> b -> *!a -> Diverge
Runs an infinite shared server thread given a function to serve a client (a handle), the initial state, and the server’s shared channel endpoint. It can be seen as an infinite sequential application of the handle function over a newly accepted session, while continuously updating the state.
Note: this only works with session types that use session initiation.
type SharedCounter : *S = *?Counter
type Counter : 1S = +{ Inc: Wait
, Dec: Wait
, Get: ?Int ; Wait
}
-- | Handler for a counter
counterService : Int -> dualof Counter 1-> Int
counterService i (Inc c) = close c ; i + 1
counterService i (Dec c) = close c ; i - 1
counterService i (Get c) = c |> send i |> close ; i
-- | Counter server
runCounterServer : dualof SharedCounter -> Diverge
runCounterServer = runServer @Counter @Int counterService 0
Output and input streams
OutStream
type OutStream : 1S = +{ PutChar : !Char ; OutStream
, PutStr : !String ; OutStream
, PutStrLn: !String ; OutStream
, SClose : Close
}
The OutStream type describes output streams (such as stdout, stderr and write mode files). PutChar outputs a character, PutStr outputs a string, and PutStrLn outputs a string followed by the newline character (\n). Operations in this channel must end with the Close option.
OutStreamProvider
type OutStreamProvider : *S = *?OutStream
Unrestricted session type for the OutStream type.
InStream
type InStream : 1S = +{ GetChar: ?Char ; InStream
, GetLine: ?String ; InStream
, IsEOF : ?Bool ; InStream
, SWait : Wait
}
The InStream type describes input streams (such as stdin and read files). GetChar reads a single character, GetLine reads a line, and IsEOF checks for the EOF (End-Of-File) token, i.e., if an input stream reached the end. Operations in this channel end with the SWait option.
InStreamProvider
type InStreamProvider : *S = *?InStream
Unrestricted session type for the OutStream type.
hCloseOut
hCloseOut : OutStream -> ()
Closes an OutStream channel endpoint. Behaves as a close.
hPutChar
hPutChar : Char -> OutStream -> OutStream
Sends a character through an OutStream channel endpoint. Behaves as |> select PutChar |> send.
hPutStr
hPutStr : String -> OutStream -> OutStream
Sends a String through an OutStream channel endpoint. Behaves as |> select PutString |> send.
hPutStrLn
hPutStrLn : String -> OutStream -> OutStream
Sends a string through an OutStream channel endpoint, to be output with the newline character. Behaves as |> select PutStringLn |> send.
hPrint
hPrint : forall a:*T . a -> OutStream -> OutStream
Sends the string representation of a value through an OutStream channel endpoint, to be outputed with the newline character. Behaves as hPutStrLn (show @t v), where v is the value to be sent and t its type.
hPutChar_
hPutChar_ : Char -> OutStreamProvider -> ()
Unrestricted version of hPutChar. Behaves the same, except it first receives an OutStream channel endpoint (via session initiation), executes an hPutChar and then closes the enpoint with hCloseOut.
hPutStr_
hPutStr_ : String -> OutStreamProvider -> ()
Unrestricted version of hPutStr. Behaves similarly, except that it first receives an OutStream channel endpoint (via session initiation), executes an hPutStr and then closes the enpoint with hCloseOut.
hPutStrLn_
hPutStrLn_ : String -> OutStreamProvider -> ()
Unrestricted version of hPutStrLn. Behaves similarly, except that it first receives an OutStream channel endpoint (via session initiation), executes an hPutStrLn and then closes the enpoint with hCloseOut.
hPrint_
hPrint_ : forall a:*T . a -> OutStreamProvider -> ()
Unrestricted version of hPrint. Behaves similarly, except that it first receives an OutStream channel endpoint (via session initiation), executes an hPrint and then closes the enpoint with hCloseOut.
hCloseIn
hCloseIn : InStream -> ()
Closes an InStream channel endpoint. Behaves as a close.
hGetChar
hGetChar : InStream -> (Char, InStream)
Reads a character from an InStream channel endpoint. Behaves as |> select GetChar |> receive.
hGetLine
hGetLine : InStream -> (String, InStream)
Reads a line (as a string) from an InStream channel endpoint. Behaves as |> select GetLine |> receive.
hIsEOF
hIsEOF : InStream -> (Bool, InStream)
Checks if an InStream reached the EOF token that marks where no more input can be read. Does the same as |> select IsEOF |> receive.
hGetContent
hGetContent : InStream -> (String, InStream)
Reads the entire content from an InStream (i.e. until EOF is reached). Returns the content as a single string and the continuation channel.
hGetChar_
hGetChar_ : InStreamProvider -> Char
Unrestricted version of hGetChar. Behaves the same, except it first receives an InStream channel endpoint (via session initiation), executes an hGetChar and then closes the enpoint with hCloseIn.
hGetLine_
hGetLine_ : InStreamProvider -> String
Unrestricted version of hGetLine. Behaves the same, except it first receives an InStream channel endpoint (via session initiation), executes an hGetLine and then closes the enpoint with hCloseIn.
hGetContent_
hGetContent_ : InStreamProvider -> String
Unrestricted version of hGetContent. Behaves the same, except it first receives an InStream channel endpoint (via session initiation), executes an hGetContent and then closes the endpoint with hCloseIn.
Standard IO
| Function | Type | Description |
|---|---|---|
stdout | OutStreamProvider | Standard output stream. Prints to the console. |
putChar | Char -> () | Prints a character to stdout. Behaves the same as hPutChar_ c stdout, where c is the character to be printed. |
putStr | String -> () | Prints a string to stdout. Behaves the same as hPutStr_ s stdout, where s is the string to be printed. |
putStrLn | String -> () | Prints a string to stdout, followed by the newline character \n. Behaves as hPutStrLn_ s stdout, where s is the string to be printed. |
print | forall a:*T . a -> () | Prints the string representation of a given value to stdout, followed by the newline character \n. Behaves the same as hPrint_ @t v stdout, where v is the value to be printed and t its type. |
stderr | OutStreamProvider | Standard error stream. Prints to the console. |
stdin | InStreamProvider | Standard input stream. Reads from the console. |
getChar | Char | Reads a single character from stdin. |
getLine | String | Reads a single line from stdin. |
File types
FilePath
type FilePath = String
File paths.
FileHandle
data FileHandle = FileHandle ()
IOMode
data IOMode = ReadMode | WriteMode | AppendMode