Last active
November 26, 2018 16:25
-
-
Save zypeh/ac8bef3c1582930a0aae61c61f0480ca to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- single line comment, no multi-line comment allowed. Keep it simple, okay ? | |
-- https://futhark-lang.org/blog/2017-10-10-block-comments-are-a-bad-idea.html | |
--------------------------------------------------- | |
-- Functions and Values Assignment -- | |
--------------------------------------------------- | |
let varname = 1 | |
let varname_with_type: Bool = true | |
-- ^-- values name ^-- type | |
-- No semicolon needed, but if you want ... use semicolons. | |
let varname = 1; let varname_with_type: Bool = true | |
-- For functions, it is just another value. | |
let sumOfSquare x y = x ^ 2 + y ^ 2 | |
let sumOfSquareWithTypeDefinition (x: i8) (y: i8) : i8 = x ^ 2 + y ^ 2 | |
-- ^-- function name ^ ^ ^-- function return type | |
-- | ` variable type | |
-- `-- variable name | |
-- You will need this anonymous function, aka clousure, lambda... | |
\x y z : Bool = x + y + z | |
let f = \x y z : Bool = x + y + z | |
let f x y z : Bool = x + y + z | |
-- This is a tuple, immutable, can store different types of data | |
(1, true, "abc") | |
-- Records, aka objects, named tuple, dict | |
-- Performance wise, it should be a codata, which only created when needed. | |
-- Heterogeneous data, can derive operation, has static fields that can be | |
-- guaranteed. | |
data Student = { id: i32, class: string } -- type definition | |
let zypeh = Student { id=1, class="abc" } | |
-- ^-- can be replace by newline | |
let zypeh = Student { | |
id=1 -- like this | |
class="abc" | |
} | |
let zypeh: Student = Student { id=1, class="abc" } | |
-- ^-- optional | |
zypeh.id = 2 -- assign twice | |
--------------------------------------------------- | |
-- Types Bindings and Aliasing -- | |
--------------------------------------------------- | |
data Bool' = Bool | |
-- `CustomBool` is just an alias for `Bool` (boolean type) | |
-- It does not create a distinct types: there are interchangable in the code | |
-- Here comes the opinionated part, for data types the first | |
-- letter should be uppercase. And variable should not messed with the dataTypes | |
--------------------------------------------------- | |
-- Algebraic Data Types -- | |
--------------------------------------------------- | |
-- Enumeration, sum types | |
data Animal = Cat | Dog | Fish | Bird | |
-- Product types, or you can say record, it is the same | |
data AnimalClass = { | |
Common: Animal | |
Rare: [String] | |
} | |
-- Algebraic data types let you define types recursively. | |
data Nat = Z | S Nat -- Do you know this is Peano encoding ? | |
-- Support newline, no worries | |
data Nat = | |
| Z | |
| S Nat | |
-- Or ... note that the white space beneath is not count | |
-- as identation | |
data Nat = Z | |
| S Nat | |
-- Why I am using `data` as the type declaration identifier? | |
-- Because I want to unify the algrabraic data type into one. | |
-- Since I am practising dependent type, so I think it will be | |
-- okay, probably. hmmmmm~ | |
--------------------------------------------------- | |
-- Pattern matching -- | |
--------------------------------------------------- | |
match value with | |
| S n => println!("{}", n) | |
| Z => println! "zero" | |
--^-- indentation no needed, but newline required | |
-- Can replace newline with newline, but not recommended | |
-- Pattern matching is useful when you wish to deconstruct | |
-- algrebraic data types, binding variable in-place or do exhaustive | |
-- case split. | |
data Animal = Cat | Dog | Fish | Bird | |
let can_swim = \(animal:Animal) : Bool = match animal | |
| Fish => true | |
| _ => false | |
-- ^-- Use `_` (underscore) to match any case or do padding when deconstruction | |
can_swim Cat -- return false | |
--------------------------------------------------- | |
-- Procedure, pipeline and the-M-word, hmmmm~ -- | |
--------------------------------------------------- | |
-- First, we are happily to introduce the thin arrow. | |
-- Which is `<-` and `->` . | |
-- We can use `->` to do pipeline. (Just like F#'s `|>`) | |
let length_of_something = [1,2,3] | |
-> concat [4,5,6] | |
-> map \x => x + 1 | |
-> len | |
-- Also, newline can be replace using semicolon also, but not | |
-- recommended, which is equivalent to | |
-- [1,2,3];->concat [4,5,6];->map \x => x + 1;->len | |
-- Which is equivalent to | |
-- len . map \x => x + 1 . concat [4, 5, 6] [1, 2, 3] | |
-- Secondly, we are happily to introduce the do-block. | |
do { ... } | |
do { | |
x <- getline!() -- IO related stuff. | |
x -> concat "!!!" -- Can use pipeline operator in do-block | |
<- println!("{}", x) | |
} | |
-- WIP: IO Lift, Transformer | |
-- WIP: exceptions, errors handling | |
-- WIP: async-await example | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment