Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/add-exercise
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ END_TEST
cat << END_STUB > "exercises/practice/${slug}/${slug_pascal}.roc"
module [${slug_camel}]

${slug_camel} = \myArg ->
${slug_camel} = |my_arg|
crash "Please implement the '${slug_camel}' function"
END_STUB

Expand Down
2 changes: 1 addition & 1 deletion bin/install-roc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
function download_alpha_release() {
local install_dir="${1}"
local install_file="${install_dir}/roc.tar.gz"
local release_url="https://github.com/roc-lang/roc/releases/download/0.0.0-alpha2-rolling/roc-linux_x86_64-0-alpha2-rolling.tar.gz"
local release_url="https://github.com/roc-lang/roc/releases/download/alpha3-rolling/roc-linux_x86_64-alpha3-rolling.tar.gz"
mkdir -p "${install_dir}"
wget -q -O ${install_file} ${release_url}
tar -xzf "${install_file}" -C "${install_dir}" --strip-components 1
Expand Down
7 changes: 4 additions & 3 deletions docs/SNIPPET.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.19.0/Hj-J_zxz7V9YurCSTFcFdu6cQJie4guzsPMUi5kBYUk.tar.br" }
app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.19.0/Hj-J_zxz7V9YurCSTFcFdu6cQJie4guzsPMUi5kBYUk.tar.br" }

import pf.Stdout

factorial = \number ->
factorial = |number|
when number is
1 -> 1
n -> n * factorial (n - 1)

expect factorial 5 == 1 * 2 * 3 * 4 * 5

main! = |_args|
result = factorial 20 |> Num.toStr
result = factorial 20 |> Num.to_str
Stdout.line! "factorial 20 = ${result}"
18 changes: 9 additions & 9 deletions exercises/practice/accumulate/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@ expect
{% endfor %}

reverse : Str -> Str
reverse = \str ->
Str.toUtf8 str
reverse = |str|
Str.to_utf8 str
|> List.reverse
|> Str.fromUtf8
|> Result.withDefault ""
|> Str.from_utf8
|> Result.with_default ""

to_upper : Str -> Str
to_upper = \str ->
Str.toUtf8 str
|> List.map \byte ->
to_upper = |str|
Str.to_utf8 str
|> List.map |byte|
if 'a' <= byte && byte <= 'z' then
byte - 'a' + 'A'
else
byte
|> Str.fromUtf8
|> Result.withDefault ""
|> Str.from_utf8
|> Result.with_default ""
2 changes: 1 addition & 1 deletion exercises/practice/affine-cipher/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ expect
key = {a: {{ case["input"]["key"]["a"] }}, b: {{ case["input"]["key"]["b"] }}}
result = {{ case["property"] | to_snake }} phrase key
{%- if case["expected"]["error"] %}
result |> Result.isErr
result |> Result.is_err
{%- else %}
expected = Ok {{ case["expected"] | to_roc }}
result == expected
Expand Down
2 changes: 1 addition & 1 deletion exercises/practice/all-your-base/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {{ exercise | to_pascal }} exposing [{{ cases[0]["property"] | to_snake }
expect
result = {{ case["property"] | to_snake }} { input_base: {{ case["input"]["inputBase"] | to_roc }}, output_base: {{ case["input"]["outputBase"] | to_roc }}, digits: {{ case["input"]["digits"] | to_roc }} }
{%- if case["expected"]["error"] %}
result |> Result.isErr
result |> Result.is_err
{%- else %}
result == Ok {{ case["expected"] }}
{%- endif %}
Expand Down
2 changes: 1 addition & 1 deletion exercises/practice/allergies/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ expect
result == {{ case["expected"] | to_roc }}
{%- else %}
result = set {{ case["input"]["score"] }}
result == Set.fromList [{{ case["expected"] | map('to_pascal') | join(", ") }}]
result == Set.from_list [{{ case["expected"] | map('to_pascal') | join(", ") }}]
{%- endif %}

{% endfor %}
Expand Down
2 changes: 1 addition & 1 deletion exercises/practice/alphametics/.meta/Example.roc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ solve = |problem|

# We can represent the equation as a dictionary of the letters mapped to their coefficients
# when we simplify the equation. For example, we can write AB + A + B == C as 11A + 2B + (-1)C == 0.
# That then becomes this dictionary: `Dict.fromList [('A', 11), ('B', 2), ('C', -1)]
# That then becomes this dictionary: `Dict.from_list [('A', 11), ('B', 2), ('C', -1)]
equation =
List.walk(
addends,
Expand Down
4 changes: 2 additions & 2 deletions exercises/practice/alphametics/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import {{ exercise | to_pascal }} exposing [{{ cases[0]["property"] | to_snake }
expect
result = {{ case["property"] | to_snake }} {{ case["input"]["puzzle"] | to_roc }}
{%- if case["expected"] %}
Result.withDefault result [] |> Set.fromList == Set.fromList [
Result.with_default result [] |> Set.from_list == Set.from_list [
{%- for letter, value in case["expected"].items() %}
('{{ letter }}', {{ value }}),
{%- endfor %}
]
{%- else %}
Result.isErr result
Result.is_err result
{%- endif %}

{% endfor %}
2 changes: 1 addition & 1 deletion exercises/practice/binary-search/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {{ exercise | to_pascal }} exposing [{{ cases[0]["property"] | to_snake }
expect
result = {{ case["input"]["array"] | to_roc }} |> {{ case["property"] | to_snake }} {{ case["input"]["value"] }}
{%- if case["expected"]["error"] %}
Result.isErr result
Result.is_err result
{%- else %}
result == Ok {{ case["expected"] }}
{%- endif %}
Expand Down
2 changes: 1 addition & 1 deletion exercises/practice/binary/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ expect
{%- if case["expected"] is not none %}
result == Ok {{ case["expected"] | to_roc }}
{%- else %}
result |> Result.isErr
result |> Result.is_err
{%- endif %}

{% endfor %}
8 changes: 4 additions & 4 deletions exercises/practice/bowling/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
import {{ exercise | to_pascal }} exposing [Game, create, roll, score]

replay_game : List U64 -> Result Game _
replay_game = \rolls ->
replay_game = |rolls|
new_game = create? {}
rolls
|> List.walkUntil (Ok new_game) \state, pins ->
|> List.walk_until (Ok new_game) \state, pins ->
when state is
Ok game ->
when game |> roll pins is
Expand All @@ -29,7 +29,7 @@ expect
game |> {{ case["property"] | to_snake }} {{ case["input"]["roll"] }}
{%- endif %}
{%- if case["expected"]["error"] %}
result |> Result.isErr
result |> Result.is_err
{%- else %}
result == Ok {{ case["expected"] | to_roc }}
{%- endif %}
Expand All @@ -39,7 +39,7 @@ expect
expect
rolls = {{ case["input"]["previousRolls"] | to_roc }}
result = replay_game rolls
result |> Result.isOk
result |> Result.is_ok

{%- endif %}

Expand Down
2 changes: 1 addition & 1 deletion exercises/practice/change/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ expect
coins = {{ case["input"]["coins"] | to_roc }}
result = coins |> {{ case["property"] | to_snake }} {{ case["input"]["target"] }}
{%- if case["expected"]["error"] %}
result |> Result.isErr
result |> Result.is_err
{%- else %}
result == Ok {{ case["expected"] | to_roc }}
{%- endif %}
Expand Down
4 changes: 2 additions & 2 deletions exercises/practice/circular-buffer/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {{ exercise | to_pascal }} exposing [create, read, write, overwrite, clea

{% for case in cases -%}
# {{ case["description"] }}
run_operations{{ loop.index }} = \_ ->
run_operations{{ loop.index }} = |_|
result =
create { capacity: {{ case["input"]["capacity"] }} }
{%- for op in case["input"]["operations"] -%}
Expand Down Expand Up @@ -41,6 +41,6 @@ run_operations{{ loop.index }} = \_ ->
expect

result = run_operations{{ loop.index }} {}
result |> Result.isOk
result |> Result.is_ok

{% endfor %}
2 changes: 1 addition & 1 deletion exercises/practice/collatz-conjecture/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {{ exercise | to_pascal }} exposing [steps]
expect
result = {{ case["property"] | to_snake }} {{ case["input"]["number"] }}
{%- if case["expected"]["error"] %}
Result.isErr result
Result.is_err result
{%- else %}
result == Ok {{ case["expected"] }}
{%- endif %}
Expand Down
6 changes: 3 additions & 3 deletions exercises/practice/complex-numbers/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

import {{ exercise | to_pascal }} exposing [real, imaginary, add, sub, mul, div, conjugate, abs, exp]

is_approx_eq = \z1, z2 ->
z1.re |> Num.isApproxEq z2.re {} && z1.im |> Num.isApproxEq z2.im {}
is_approx_eq = |z1, z2|
z1.re |> Num.is_approx_eq z2.re {} && z1.im |> Num.is_approx_eq z2.im {}

{% for supercase in cases %}
###
Expand All @@ -30,7 +30,7 @@ expect
expected = {{ plugins.to_complex_number(subcase["expected"]) }}
result |> is_approx_eq expected
{%- else %}
result |> Num.isApproxEq {{ subcase["expected"] | to_roc }} {}
result |> Num.is_approx_eq {{ subcase["expected"] | to_roc }} {}
{%- endif %}
{%- elif subcase["input"]["z1"] %}
expect
Expand Down
2 changes: 1 addition & 1 deletion exercises/practice/custom-set/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ expect
# {{ case["description"] }}
expect
set = from_list {{ case["input"]["set"] | to_roc }}
result = set |> to_list |> List.sortAsc
result = set |> to_list |> List.sort_asc
expected = {{ case["expected"] | to_roc }}
result == expected

Expand Down
2 changes: 1 addition & 1 deletion exercises/practice/diamond/.meta/Example.roc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ unwrap_from_utf8 : List U8 -> Str
unwrap_from_utf8 = |chars|
when chars |> Str.from_utf8 is
Ok(result) -> result
Err(_) -> crash("Str.fromUtf8 should never fail here")
Err(_) -> crash("Str.from_utf8 should never fail here")

diamond : U8 -> Str
diamond = |letter|
Expand Down
2 changes: 1 addition & 1 deletion exercises/practice/diamond/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {{ exercise | to_pascal }} exposing [{{ exercise | to_snake }}]
# {{ case["description"] }}
expect
result = {{ exercise | to_snake }} '{{ case["input"]["letter"] }}'
expected = {{ case["expected"] | to_roc_multiline_string | replace(" ", "·") | indent(8) }} |> Str.replaceEach "·" " "
expected = {{ case["expected"] | to_roc_multiline_string | replace(" ", "·") | indent(8) }} |> Str.replace_each "·" " "
result == expected

{% endfor %}
14 changes: 7 additions & 7 deletions exercises/practice/dominoes/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,32 @@ Domino : (U8, U8)

## Rotate each domino if needed to ensure that the small side is on the left
canonicalize : List Domino -> List Domino
canonicalize = \dominoes ->
canonicalize = |dominoes|
dominoes
|> List.map \domino ->
|> List.map |domino|
if domino.0 > domino.1 then (domino.1, domino.0) else domino

## Ensure that the given result is Ok and is a valid chain for the
## given list of dominoes
is_valid_chain_for : Result (List Domino) _, List Domino -> Bool
is_valid_chain_for = \maybeChain, dominoes ->
is_valid_chain_for = |maybeChain, dominoes|
when maybeChain is
Err _ -> Bool.false
Ok chain ->
if Set.fromList (canonicalize chain) == Set.fromList (canonicalize dominoes) then
if Set.from_list (canonicalize chain) == Set.from_list (canonicalize dominoes) then
when chain is
[] -> Bool.true
[.., last] ->
chain
|> List.walkUntil (Ok last) \state, domino ->
|> List.walk_until (Ok last) \state, domino ->
when state is
Err InvalidChain -> crash "Unreachable"
Ok previous ->
if previous.1 == domino.0 then
Continue (Ok domino)
else
Break (Err InvalidChain)
|> Result.isOk
|> Result.is_ok
else
Bool.false

Expand All @@ -52,7 +52,7 @@ expect
{%- if case["expected"] %}
result |> is_valid_chain_for {{ to_list_of_pairs(case["input"]["dominoes"]) }}
{%- else %}
result |> Result.isErr
result |> Result.is_err
{%- endif %}

{% endfor %}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ When things go wrong, it's important to give the end user a nice and helpful err
Luckily, Roc allows you to carry payload (i.e., data) inside your `Err` tag. It's tempting to carry an error message directly (e.g., `Err "User #42 was not found"`), and this may be fine in some simple cases, but this has several limitations:

- you might not have enough context inside the function that detects the error to produce a sufficiently helpful error message.
- For example, the `Str.toU64` function can be used to parse all sorts of integers: days, seconds, user IDs, and more. If the error message just says `Could not convert string "0.5" to a positive integer`, the user may not have enough context to solve the issue.
- For example, the `Str.to_u64` function can be used to parse all sorts of integers: days, seconds, user IDs, and more. If the error message just says `Could not convert string "0.5" to a positive integer`, the user may not have enough context to solve the issue.
- in many cases your error handling code may need to handle some errors differently than others. However, if the errors only carry string payloads, your error handling code will have to parse that string to know what problem occurred: this is inefficient and it can easily break if the error message is ever tweaked.
- if your website is multilingual, you will need to translate the error message to the user's language. It's going to be much easier to do that if the error payload is machine-friendly data rather than an English string.

Expand Down
4 changes: 2 additions & 2 deletions exercises/practice/etl/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import {{ exercise | to_pascal }} exposing [transform]
# {{ case["description"] }}
expect
legacy =
Dict.fromList [
Dict.from_list [
{%- for score, letters in case["input"]["legacy"].items() %}
({{score}}, {{ letters | to_roc | replace("\"", "'") }}),
{%- endfor %}
]
expected =
Dict.fromList [
Dict.from_list [
{%- for letter, score in case["expected"].items() %}
('{{letter}}', {{ score }}),
{%- endfor %}
Expand Down
2 changes: 1 addition & 1 deletion exercises/practice/forth/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Forth exposing [evaluate]
expect
result = evaluate {{ innerCase["input"]["instructions"] | join('\n') | to_roc_multiline_string | indent(8) }}
{%- if innerCase["expected"]["error"] %}
Result.isErr result
Result.is_err result
{%- else %}
result == Ok {{ innerCase["expected"] }}
{%- endif %}
Expand Down
10 changes: 5 additions & 5 deletions exercises/practice/go-counting/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
{%- if territory == [] %}
Set.empty {}
{%- else %}
Set.fromList [
Set.from_list [
{%- for intersection in territory %}
{ x : {{ intersection[0] }}, y : {{ intersection[1] }} },
{%- endfor %}
Expand All @@ -20,24 +20,24 @@ import {{ exercise | to_pascal }} exposing [territory, territories]
## comparing tags or records containing sets sometimes returns the wrong result
## depending on the internal order of the set data, so we have to unwrap the sets
## in order to compare them properly.
compareTerritory = \maybe_result, maybe_expected ->
compareTerritory = |maybe_result, maybe_expected|
when (maybe_result, maybe_expected) is
(Ok result, Ok expected) -> result.owner == expected.owner && result.territory == expected.territory
_ -> Bool.false

compareTerritories = \maybe_result, maybe_expected ->
compareTerritories = |maybe_result, maybe_expected|
when (maybe_result, maybe_expected) is
(Ok result, Ok expected) -> result.black == expected.black && result.white == expected.white && result.none == expected.none
_ -> Bool.false

{% for case in cases -%}
# {{ case["description"] }}
expect
board = {{ case["input"]["board"] | to_roc_multiline_string | replace(" ", "·") | indent(8) }} |> Str.replaceEach "·" " "
board = {{ case["input"]["board"] | to_roc_multiline_string | replace(" ", "·") | indent(8) }} |> Str.replace_each "·" " "
result = board |> {{ case["property"] | to_snake }}
{%- if case["property"] == "territory" %} { x : {{ case["input"]["x"] }}, y : {{ case["input"]["y"] }} }{% endif %}
{%- if case["expected"]["error"] %}
result |> Result.isErr
result |> Result.is_err
{%- elif case["expected"]["owner"] %}
expected = Ok {
owner: {{ case["expected"]["owner"] | to_pascal }},
Expand Down
2 changes: 1 addition & 1 deletion exercises/practice/grains/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ expect
expect
result = grains_on_square {{ subcase["input"]["square"] }}
{%- if subcase["expected"]["error"] %}
Result.isErr result
Result.is_err result
{%- else %}
result == Ok {{ subcase["expected"] }}
{%- endif %}
Expand Down
2 changes: 1 addition & 1 deletion exercises/practice/hamming/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {{ exercise | to_pascal }} exposing [{{ cases[0]["property"] | to_snake }
expect
result = {{ case["property"] | to_snake }} {{ case["input"]["strand1"] | to_roc }} {{ case["input"]["strand2"] | to_roc }}
{%- if case["expected"]["error"] %}
Result.isErr result
Result.is_err result
{%- else %}
result == Ok {{ case["expected"] }}
{%- endif %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ expect
digits = {{ case["input"]["digits"] | to_roc }}
result = digits |> {{ case["property"] | to_snake }} {{ case["input"]["span"] | to_roc }}
{%- if case["expected"]["error"] %}
result |> Result.isErr
result |> Result.is_err
{%- else %}
expected = Ok {{ case["expected"] | to_roc }}
result == expected
Expand Down
Loading