Skip to content

Instantly share code, notes, and snippets.

@motoyasu-yamada
Created September 27, 2022 04:37
Show Gist options
  • Save motoyasu-yamada/274fa60aeac26c66344f7ec3e4317403 to your computer and use it in GitHub Desktop.
Save motoyasu-yamada/274fa60aeac26c66344f7ec3e4317403 to your computer and use it in GitHub Desktop.
use Either Right Left
{{ This type is used to capture the expected error message }}
unique type bowling.Error = Error Text
{{
{score} takes in a list of numbers representing the pins knocked down for each roll of the bowling game, and should return either the total score or an error.
}}
bowling.score : [Nat] -> Either Error Nat
bowling.score rolls =
match calcFrames 1 (0, rolls) with
None -> Left (Error "Score cannot be taken until the end of the game")
Some(total, rolls) ->
if rolls === [] then
Right(total)
else
Left (Error "Score is taken over the end of the game")
bowling.calcFrames : Nat -> (Nat, [Nat]) -> Optional (Nat, [Nat])
bowling.calcFrames frame prev =
match calcFrame frame prev with
None -> None
Some (total, rolls) ->
if frame == 10 then
Some(total, rolls)
else
calcFrames (frame + 1) (total, rolls)
bowling.calcFrame : Nat -> (Nat, [Nat]) -> Optional (Nat, [Nat])
bowling.calcFrame frame prev =
(prevTotal, prevRolls) = prev
match pop2 prevRolls with
None -> None
Some (f1, r1, f2, r2) ->
if f1 + f2 < 10 then
Some(prevTotal + f1 + f2, r2)
else
match pop r2 with
None -> None
Some (f3, r3) ->
if (frame == 10) then
Some(prevTotal + f1 + f2 + f3, r3)
else if f1 == 10 then
Some(prevTotal + f1 + f2 + f3, r1)
else
Some(prevTotal + f1 + f2 + f3, r2)
bowling.pop2 : [Nat] -> Optional (Nat, [Nat], Nat, [Nat])
bowling.pop2 stream =
match pop stream with
None -> None
Some (v1, s1) ->
match pop s1 with
None -> None
Some (v2, s2) -> Some (v1, s1, v2, s2)
bowling.pop : [Nat] -> Optional (Nat, [Nat])
bowling.pop stream =
match List.at 0 stream with
None -> None
Some(v) -> Some (v, List.drop 1 stream)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment