Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ---------------------------------------------------------------------------------------
- -- Imports
- use std::collections::HashMap -- Alias HashMap module, use it now as HashMap::new/1
- use std::collections::HashMap::* -- Import HashMap functions, use it now as: new/1
- use std::io::Error::Error -- Import Error variant and every variant name into namespace
- -- This means that now I can use:
- -- | Error::CannotOpenFile
- -- | CannotOpenFile
- ---------------------------------------------------------------------------------------
- -- Record types.
- -- Used to give an alias to a record.
- -- This is totally equivalent to: { name : String, age : Int }
- type User =
- name : String
- age : Int
- -- Type variants
- type UserStatus =
- | LoggedIn
- | LoggedOut(DateTime)
- -- HKT
- type List =
- | Cons(a, List(a))
- | Nil
- -- Updating type field
- update_name(user : User) -> User =
- { user | name = "Updated: ${user.name}" }
- ---------------------------------------------------------------------------------------
- -- Protocols
- -- Inside the definition of a protocol, self is used
- -- to refere to the type implementing it
- protocol Debug =
- fmt(Self) -> String
- -- 2 generic types here:
- -- self: probably List(a)
- -- a : type of a single element inside List
- protocol Iterator =
- next(Self) -> Result(a)
- ---------------------------------------------------------------------------------------
- -- Implementation block
- impl Debug for User =
- fmt(self) -> String =
- "{ name = ${self.name}, age = ${self.age} }"
- -- Extension functions
- -- Can be used in any module on any exported type
- -- In case of conflincting signatures, an error is thrown.
- -- Overloading is allowed.
- impl User =
- print_name(self) -> Unit =
- IO::println(self.name)
- impl User =
- print_name(self, out : Writer) -> Unit =
- Writer::write(out, self.name)
- impl User =
- print_name(self, console : Console) -> Unit =
- Console::println(console, self.name)
- -- HKT applied to impl block
- impl Iterator(a) for List(a) =
- next(self) -> Result(a) =
- pass
- ---------------------------------------------------------------------------------------
- -- Constants
- const PI = "3.14"
- pub const SERVER_URL = "https://google.com"
- ---------------------------------------------------------------------------------------
- -- Assignment
- -- Only possible inside let block.
- something() -> String =
- let
- result = "hello world"
- in
- result
- -- Pattern matching in let returns the value
- -- if it doesn't match.
- something() -> String =
- let
- Ok(user) = get_user_from_cache() -- Could return Error(_)
- Ok(age) =
- case user.age of
- | it < 18 -> Error()
- | _ -> Ok(user.age)
- in
- pass
- -- With destructuring
- something() -> String =
- let
- {name, age} = { name = "Gabriel", age = 23 }
- (first, second) = ("First", "Second")
- in
- pass
- ---------------------------------------------------------------------------------------
- -- Conditionals
- log(val : Debug) -> Unit =
- case System::env() of
- | Prod -> ()
- | _ -> IO::println(val)
- -- To simulate an if/else, use case of without arguments.
- -- It expects every left arm of a branch to evaluate to a boolean value.
- something(name : String) -> String =
- case of
- | isPeter(name) -> pass
- | isMario(name) -> pass
- | isAngelo(name) -> pass
- ---------------------------------------------------------------------------------------
- -- Functions
- -- The most basic function. Its always required to specify the return type,
- -- even if it's Unit.
- something() -> Unit =
- pass
- -- With params and return value
- new_user(name : String, age : Int) -> User =
- pass
- -- With default value
- new_user(name : String, age : Int = 18) -> User =
- pass
- -- With generic type
- append_to_list(list : List(a), elem : a) -> List(a) =
- pass
- ---------------------------------------------------------------------------------------
- -- Lambdas
- double(coll : List(Int)) -> List(Int) =
- Enum::map(coll) { it * 2 }
- ---------------------------------------------------------------------------------------
- -- Function call
- -- From current scope
- something() -> Int =
- multiply(2, 3)
- -- From an external module
- something() -> HashMap(String, Int) =
- HashMap::new()
- -- With named arguments
- something() -> Int =
- multiply(first = 2, second = 3)
- ---------------------------------------------------------------------------------------
- -- Pipe operator
- -- Pipes into the first argument of the function.
- -- Every function requires brackets.
- something() -> String =
- divide(30, 10)
- |> multiply(10)
- |> add(5)
- |> toString()
- ---------------------------------------------------------------------------------------
- -- Visibility modifiers
- -- Private, only visible inside module
- something() -> Unit =
- pass
- -- Public, visible to other modules as well
- pub something() -> Unit =
- pass
- ---------------------------------------------------------------------------------------
- -- Annotations
- -- since("1.0.0")
- -- deprecated("Use String.join/3 instead", level = WARNING)
- join(s : List(String), sep : String) -> String =
- pass
- ---------------------------------------------------------------------------------------
- -- Testing
- -- First class citizien, with custom constructs.
- suite "User" =
- -- Run initially
- init =
- let
- user = User::new("Gabriel")
- in
- { user = user }
- -- Run before each test
- before =
- pass
- -- Run after each test
- after =
- pass
- test "name should always be Gabriel" =
- assert(True) { self.user.name == "Gabriel" }
- test "name should never be another thing than Gabriel" =
- assert(False) { self.user.name == "Luigi" }
- test "should not be present in cache by default" =
- let
- Ok(cache) = get_global_cache()
- in
- assert(Error(Cache::Error::ValueNotPresent)) {
- Cache::get(cache, "user")
- }
- ---------------------------------------------------------------------------------------
- -- Things in the standard library
- -- Option and Result replaced by Result
- -- Two type exists: Result/1 and Result/2
- -- It allows always for exaustive pattern matching
- type Result =
- | Ok(a)
- | Error(e = CommonError)
- type CommonError =
- | NotFound
- | InvalidFormat
- -- Usage
- something() -> Result(Int) =
- case of
- | False -> Ok()
- | False -> Error(Nothing)
- | True -> Error(InvalidFormat)
- case something() of
- | Ok(val) -> IO::println(val)
- | Error(NotFound) -> IO::println("Not Found")
- | Error(_) -> pass
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement