Solutions to Exercises
Solution 3.1. There’s no standard answer to this one. Here’s ours:
{1..2} | %[3]
Solution 3.2.
[%[2], {517}, []]
Solution 4.1.
4
Solution 4.2.
["melo", "haha", "deon"]
Solution 4.3.
Nope. You can only append two values of the same type. "1" ++ [2]
fails to type-check and does not compile:
melorun> "1" ++ [2]
Melodeon compilation failed
~/.melorun.melo.tmp:3: error: cannot append values of types %[1] and [{2}]
"1" ++ [2]
^~~~~~~~~~
Solution 4.4.
{35} | %[8]
Solution 4.5.
Two alternatives:
[x * x for x in [1, 10, 100]]
for x in [1, 10, 100] collect x * x
Solution 4.6. WIP
Solution 4.7.
let x = [1, 2] in
loop 2 do
set! x = x ++ x
return x
Solution 6.1.
def six1<T>(x: T) =
if x is Nat then x + 1
else (if x is [Any;] then x ++ [1]
else if x is %[] then x ++ "1"
else fail!)
Solution 6.2.
# swaps the ith and jth indices of vec
def swap<$n, T>(vec: [T; $n], i: Nat, j: Nat) =
let v_i = vec[i] in
let v_j = vec[j] in
vec[i => v_j][j => v_i]
Solution 6.3.
The function doesn’t compile, because the length of vec
is unknown from its type definition. We can use a constant generic parameter to solve this problem:
def f<$n>(vec: [Nat;$n]) =
for i in vec fold accum = 0 :: Nat with accum + i
Solution 6.4.
def ident<$n>(s: %[2 * $n + 1]) =
s
Solution 6.5.
# swap is defined in Solution 6.2
def bubble_sort<$n>(vec: [Nat; $n]) =
loop $n do
set! vec =
(let i = $n :: Nat in
let j = $n-1 :: Nat in
(loop $n do
set! vec =
(if j > 0
then (if vec[$n - i] > vec[$n - j]
then swap(vec, $n - i, $n - j)
else vec)
else vec);
set! i = i - 1;
set! j = j - 1;
return vec))
return vec
Note that the trick with decreasing i
and j
is for safely indexing into the vector with an expression involving $n
, so that the compiler can prove the indices are safe.
Solution 6.6.
def f(x: Any) =
if x is %[5] then "bingo!" else "keep trying!"
Solution 6.7.
Yes, the expression compiles. In each iteration of the loop, x
is mutated to the constant 7
, which doesn’t depend on x
. So the post-mutation type also doesn’t depend on the type of x
: it’s the constant {7}
. The compiler can check that {7}
is a subtype of {1..10}
, so all is good.
Solution 6.8.
1
Solution 6.9.
WIP
Solution 6.10.
No, because the input to h
needs to satisfy more than a subtype relation. It must satisfy the constraints imposed by the constant generic parameter $n
. We can see this in the REPL:
melorun> h(Point{x: 1, y: 2})
Melodeon compilation failed
~/.melorun.melo.tmp:72: error: cannot fill type variables in argument type [T; ($n + 1)], given concrete Point
h(Point{x: 1, y: 2})
^~~~~~~~~~~~~~~~~~~~