-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathexample.fi
169 lines (143 loc) · 3.92 KB
/
example.fi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# Here's a walkthrough of Fika's syntax. Please be warned that Fika is still
# an early prototype and the syntax you see here will likely change
# based on feedback from the users.
# A function definition that takes two integers as arguments
# and returns an integer.
fn sum(a: Int, b: Int) : Int do
a + b
end
# Here's a function that doesn't take any argument.
fn hello : String do
"World"
end
# true and false are keywords that of the type Bool
fn bool : Bool do
true
end
# Strings
fn hello_interpolation : String do
# Here's a string
hello = "Hello!"
world = "World"
# String can be interpolated using #{}
"#{hello} Greetings to the #{world}"
end
# This function returns a list of integers.
fn foo : List(Int) do
[1, 2, 3]
end
# A tuple is a small group of values of different types.
# A tuple does not grow dynamically and it's shape is fixed.
fn tuple : {Int, Bool} do
{1, true}
end
# Records are useful for holding data with known keys,
# for example, records from a table in a relational DB.
# Think of them as "named tuples" where each element gets a unique name.
fn rec : {foo: List(Int)} do
{foo: [1, 2, 3]}
end
# Union types
fn interval(start: Int, finish: Int) : {:error, String} | {:ok, Int} do
if start <= finish do
{:ok, finish - start}
else
{:error, "Interval cannot end before it's started"}
end
end
# The Map type holds key-value data that grows dynamically.
# Maps are useful when the types of keys and values are known
# already, but their contents change dynamically during runtime.
fn map : Map(String, List(Int)) do
{"james-bond" => [0, 0, 7]}
end
# Anonymous functions
fn anonymous_call : Int do
# f is a reference to an anonymous function
f = (x: Int, y: Int) do
x + y
end
# The anonymous function can be called using .()
f.(10, 20)
end
# This function returns a function reference.
# The signature of this function can be read as:
# "sum_ref takes no arguments and returns a function.
# The function that it returns takes two integers
# and returns another integer."
fn sum_ref : Fn(Int, Int -> Int) do
# Create reference to a named function using &
&sum(Int, Int)
end
# Calling functions using references
fn call_sum_ref : Int do
# As we saw in the case of anonymous functions, references can be used
# to call functions using .()
sum_ref().(1, 2)
end
# Use type variables when your function is generic and needs to work with
# a variety of types
fn make_pair(x: a, y: b) : {a, b} do
{x, y}
end
# Effect type
# Fika separates functions with side effects so they can be safely executed.
# Such functions are marked by the "Effect" type.
fn greet : Effect(String) do
name = io.gets("What's your name? ")
io.puts("Hello #{name}")
end
# Or operator
fn or(a: Bool, b: Bool) : Bool do
# Returns true if either a or b is true
a | b
end
# And operator
fn and(a: Bool, b: Bool) : Bool do
# Returns true if both a and b are true
a & b
end
# Not operator
fn not(a: Bool) : Bool do
# Returns true if a is false
!a
end
# Unary minus operator
fn unary_minus(a: Int) : Int do
-a
end
# Comparison operators
# >, <, ==, <=, >=, !=
fn max(a: Int, b: Int) : Int do
if a > b do
a
else
b
end
end
# Here's an example of the if-else expression.
# Notice that an if should always be followed by an else.
fn simple_if : String do
if true do
"I am the return value because the condition is true"
else
"If the condition was false, It would have been me"
end
end
# Case expressions allow you to pattern match expressions and conditionally
# execute statements
fn get_score(result: {:ok, Int} | :error) : Int do
case result do
{:ok, score} -> score
:error -> 0
end
end
# Wrap and use external functions defined in the BEAM
ext str_length(str: String) : Int = {"Elixir.String", "length", [str]}
ext list_size(l: List(Int)) : Int = {"erlang", "length", [l]}
fn string_length : Int do
str_length("Hello world")
end
fn list_length : Int do
list_size([1, 2, 3])
end