# Solutions to Exercises

Solution 3.1. There’s no standard answer to this one. Here’s ours:

``````{1..2} | %
``````

Solution 3.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" ++ ` fails to type-check and does not compile:

``````melorun> "1" ++ 
Melodeon compilation failed
~/.melorun.melo.tmp:3: error: cannot append values of types % and [{2}]
"1" ++ 
^~~~~~~~~~
``````

Solution 4.4.

``````{35} | %
``````

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 ++ 
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 % 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})
^~~~~~~~~~~~~~~~~~~~
``````