-
Notifications
You must be signed in to change notification settings - Fork 11
Home
All variables are immutable and trying to mutate a variable will result in a node
error of Identifier 'variable' has already been declared
num = 10
str = 'abcd'
bool = true
All variable declarations require a space before and after the =
sign
All operators require a space before and after them except for unary operators -
and !
b = 10 + 15 * 20
Precedence goes according to operator precedence and if a different precedence is required, wrap the expression in a parentheses ()
prec = (10 + 15) * 20
The if-then-else
construct can be written in a single line or in multiple lines (requires indents) on the new lines. The types of both the then
and else
expression should match.
c = if 10 > 3 then true else false
d = if 10 > 3
then true
else false
The let-in
construct can be used to declare variables in the local scope and use them in an expression
e = let val1 = 20 in (val1 + 43) * 2
You can have multiple variables declared in a let
expression
f = let x = 40 y = 67 z = 78 in ((7 * x) / z / y)
Lambdas are written as such:
\arg1 arg2 -> arg1 + arg2
Since lambdas are expressions, they can also be bound to identifiers:
sum = \a b -> a + b
Lambdas can be called immediately by wrapping the expression in parentheses and supplying the arguments afterwards. The arguments must be space separated.
(\arg1 arg2 -> arg1 + arg2) 1 2
Pattern matching for numbers, strings, and empty arrays is supported.
fib 0 = 0
fib 1 = 1
fib n = fib (n - 2) + fib (n - 1)
odd 0 = 'even'
odd 1 = 'odd'
odd n = odd (n % 2)
len [] = 0
len arr = 1 + len (arr.slice 1)
sum a b = a + b
Any kind of evented IO is done inside a do
block
The bind
construct consists of 3 parts:
- variable
- reverse bind operator
<-
- An IO function
There can be any number of variables before the bind operator
do
input <- getLine 'enter val: '
The value getLine
returns is bound to input
do
input <- getLine 'enter val: '
let num = parseInt input
All pure transformations should be done using let
statements. This construct is different from the let-in
construct wherein this doesn't require the in
keyword or an expression.
Currently, the following maybe
methods are supported:
maybeTrue
maybeFalse
maybeUndefined
maybeNull
maybeErr
Format: maybe<val> expression handler
If the expression
evaluates to val
the handler
is executed
do
input <- getLine 'enter val: '
let num = parseInt input
maybeTrue (num == 3) (putLine 'Got 3')
In the above example, if num == 3
evaluates to true
then putLine 'Got 3'
gets executed.
computeFact = do
input <- getLine 'enter value: '
let num = parseInt input
return (fact num)
fact
in the above example is a factorial function
defineProp
is used to assign properties to objects.
The defineProp
method takes 3 arguments
- object
- key
- value
defineProp object 'key' value
do
name <- getLine 'enter age: '
let person = {}
defineProp person 'username' name
The above example defines a key username
with value name
(as entered by the user) in the object person
delete
is used to delete a key from an object
The delete
method takes 1 argument
- object.key
delete person.username
The statement deletes the key username
from the object person
as defined in the above example
The return
keyword is used in cases when a user wants to reuse an IO block and wants to return a set of values as they require.
computeFact = do
num <- getLine 'enter value for factorial: '
let val = parseInt num
putLine val + 14
return val
In the above example, computeFact
is an IO
which can be used again as it returns a value.
do
result <- computeFact
putLine result
In the above code block, the value returned by computeFact
is bound to result
and can now be used.
An IO can be reused if the block is assigned to a variable and has a return
statement.
IO blocks without a return
statement are executed automatically and do not require to be assigned to a variable.
do
input <- getLine 'Enter a value'
putLine input
example = do
input <- getLine 'Enter a value'
return input
The difference between the above two blocks is that the 1st block will execute automatically whereas the second one needs to be bound to a variable as follows:
do
value <- example
putLine value