The for-notation extension is an extention to help programming with unique typing. Here is a simple example.

hello f = for f fwrites "your name? " s <- freadline s = chop s fwrites "Hello, " $> s $> newline return

This is interpreted as the following.

hello f = case f of f # f = f |> fwrites "your name? " (s,f) = f |> freadline s = chop s f = f |> fwrites "Hello, " $> s $> newline = f

# Basic Rules

## Beginning of the notation

The first line of the notation is the following.

... for <expression-1>

This <expression-1> will be used for a hidden object during this for-notation. The scope of this notation is indicated by indent rule.

## Simple statement

A simple statement like the following is interpreted to be complemented by the hidden object.

fwrites "your name? "

will be

f = f |> fwrites "your name? "

The '|>' operator is a pipeline operator defined in OptBase module in OptEnv library.

// pipeline operator (|>) infixl 0 //:: .a (.a -> .b) -> .b (|>) a f :== f a

## Assign statement

A statement with '<-' is an assign statement and the left variables are complemented by a tuple with the hidden object.

s <- freadline

will be

(s,f) = f |> freadline

Another example is the case when there are two left variables.

ok, i <- freadi

will be

(ok, i, f) = f |> freadi

## Bind statement

A statement with '=' is a bind statement and it is interpreted as it is.

s = chop s

## Return statement

A statement beggining with 'return' is a return statement and it is the returning statement of the for-notation. It is interpreted as it is the body of the function.

return

will be

= f

If a return statement has some arguments, a tuple with the hidden object complements the statement.

return ok, i

will be

= (ok, i, f)

# Guard statement

A line beginning with '|' is a guard. Unlike standard clean syntax, a guard of for-notation must be in a single line and does not allow including a body of the guard.

Body statements follows after the guard line with indentation. The body lines will be also interpreted as a part of for-notation.

ok, i <- freadi | not ok return -1 return i

will be interpreted as

# (ok, i, f) = f |> freadi | not ok = (-1, f) = (i, f)

# Auxiliary functions

For-notation can have auxiliary functions. Those functions also have a hidden object as the main part.

for f ok, i <- freadi i <- check ok i return i check False _ fwrites "read error\n" return -1 check True i return i

In the above sample, 'check' function is an auxiliary function of the for-notation. This function is interpreted as the following.

check False _ f # f = f |> fwrites "read error\n" = (-1, f) check True i f = (i, f)

# Continue statement

A statement beginning with 'continue' is a continue statement and it is the tail call statement of the for-notation. It is interpreted as it is the body of the function with function call.

continue next_call str

will be interpreted as

= f |> next_call str

# Except pattern

A line beginning with '?' is a except pattern. It is used for focusing a main process while handling an exceptional process with an auxiliary function.

for f ? True, i <- freadi return i except False _ fwrites "read error\n" return -1

will be interpreted as

case f of f = case f |> freadi of (True, i, f) = (i, f) (ok, i, f) = except ok i f with except False _ f # f = f |> fwrites "read error\n" = (-1, f)

If some letters or numbers follow the leading '?' without any spaces, it is interpreted as those will be added to the except function name. For example if a leading symbol is '?1' then the except function name is 'except1' and if '?_foo' then 'except_foo.'

# Nested for-notation

For-notation can be nested. Here is a sample below.

Start w = for w f <- stdio f = for f fwrites "your name? " s <- freadline fwrites "Hello, " $> s return _ <- fclose f return

The program can also be written as the following.

Start w = for w f <- stdio _ <- for f fwrites "your name? " s <- freadline fwrites "Hello, " $> s continue fclose return