Prelude

Table of contents

Builtins

(+) : 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

(==) : Int -> Int -> Bool

(/=) : Int -> Int -> Bool

(<) : Int -> Int -> Bool

(>) : Int -> Int -> Bool

(<=) : Int -> Int -> Bool

(>=) : Int -> Int -> Bool

(+.) : 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

truncate : Float -> Int

round : Float -> Int

ceiling : Float -> Int

floor : Float -> Int

recip : Float -> Float

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

fromInteger : Int -> Float

(&&) : Bool -> Bool -> Bool

(||) : Bool -> Bool -> Bool

ord : Char -> Int

chr : Int -> Char

(^^) : String -> String -> String

show : forall a:*T . a -> String

readBool : String -> Bool

readInt : String -> Int

readChar : String -> Char

fork : forall a:*T. (() 1-> a) -> ()

error : forall a:*T . String -> a

undefined : forall a:*T . a

new : forall a:1A . () -> (a, dualof a)

Creates two endpoints of a channels of the given type.

send : forall a:1T . a -> forall b:1S . !a ; b 1-> b

Sends a value on a channel. Returns the continuation channel

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 -> ()

Closes a channel.

wait : Wait -> ()

Waits for a channel to be closed.

Base

Bool

data Bool = True | False 

not : Bool -> Bool

Boolean complement

id : forall a:*T . a -> a

The identity function. Will return the exact same value.

id 5       -- 5
id "Hello" -- "Hello"

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 : 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 : 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 : 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 : 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 : forall a:*T . ((a -> a) -> (a -> a)) -> (a -> a)

Fixed-point Z combinator

fst : forall a:1T b:*T . (a, b) -> a

Extracts the first element from a pair, discarding the second.

snd : forall a:*T b:1T . (a, b) -> b

Extracts the second element from a pair, discarding the first.

Concurrency and channels

Diverge

type Diverge = ()

A mark for functions that do not terminate

sink : forall a:*T . a -> ()

Discards an unrestricted value

repeat : forall a:*T . Int -> (() -> a) -> ()

Executes a thunk n times, sequentially

main : ()
main = 
  -- print "Hello!" 5 times sequentially
  repeat @() 5 (\_:() -> putStrLn "Hello!")

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 : 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 : 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 : 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 : forall a:1T . a -> !a ; Close 1-> ()

Sends a value on a given channel and then closes the channel. Returns ().

receive_ : forall a:1T . *?a -> a

Receives a value from a star channel. Unrestricted version of receive.

send_ : forall a:1T . a -> *!a 1-> ()

Sends a value on a star channel. Unrestricted version of send.

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 : 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 : 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 : OutStream -> ()

Closes an OutStream channel endpoint. Behaves as a close.

hPutChar : Char -> OutStream -> OutStream

Sends a character through an OutStream channel endpoint. Behaves as |> select PutChar |> send.

hPutStr : String -> OutStream -> OutStream

Sends a String through an OutStream channel endpoint. Behaves as |> select PutString |> send.

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 : 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_ : 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_ : 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_ : 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_ : 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 : InStream -> ()

Closes an InStream channel endpoint. Behaves as a close.

hGetChar : InStream -> (Char, InStream)

Reads a character from an InStream channel endpoint. Behaves as |> select GetChar |> receive.

hGetLine : InStream -> (String, InStream)

Reads a line (as a string) from an InStream channel endpoint. Behaves as |> select GetLine |> receive.

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 : 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_ : 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_ : 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_ : 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

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.

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