Skip to content
Mrinal Purohit edited this page May 27, 2017 · 5 revisions

Syntax

All variables are immutable and trying to mutate a variable will result in a node error of Identifier 'variable' has already been declared

Basic variable declarations

num = 10
str = 'abcd'
bool = true

All variable declarations require a space before and after the = sign

Operators

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

if-then-else

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

let-in

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)

lambda

\arg1 arg2 -> arg1 + arg2

lambda call

(\arg1 arg2 -> arg1 + arg2) 1 2

Function declarations

Pattern matching for numbers and strings 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)

sum a b = a + b

IO blocks

Any kind of evented IO is done inside a do block

Bind

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

Assignment

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.

maybe

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

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

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

return

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.

Using an IO block

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
Clone this wiki locally