There is a problem with this implementation of nthElement
:
nthElement : List a -> Int -> Result String a
nthElement list n =
if n >= 0 then
nthElementHelper list n
else
Err ("The index must be non-negative: " ++ String.fromInt n)
nthElementHelper : List a -> Int -> Result String a
nthElementHelper list n =
case list of
[] ->
Err ("List too short by " ++ String.fromInt (n+1) ++ pluralize n "element" "elements")
x :: rest ->
if n == 0 then
Ok x
else
nthElementHelper rest (n-1)
Can you spot the problem and fix it so that it passes all the following tests?
nthElement : Test
nthElement =
describe "nthElement"
[ describe "empty list"
[ fuzz Fuzz.int "can never find the nth element of the empty list" <|
\n ->
Ch1.nthElement [] n
|> Expect.err
]
, describe "non-empty list"
[ test "it returns the 1st element" <|
\_ ->
Ch1.nthElement [1, 2, 3, 4, 5] 0
|> Expect.equal (Ok 1)
, test "it returns the 2nd element" <|
\_ ->
Ch1.nthElement [1, 2, 3, 4, 5] 1
|> Expect.equal (Ok 2)
, test "it returns the 5th element" <|
\_ ->
Ch1.nthElement [1, 2, 3, 4, 5] 4
|> Expect.equal (Ok 5)
, test "it returns an error given a negative index" <|
\_ ->
Ch1.nthElement [1, 2, 3, 4, 5] -1
|> Expect.equal (Err "The index must be non-negative: -1")
, test "it returns an error given an out of bounds index" <|
\_ ->
Ch1.nthElement [1, 2, 3, 4, 5] 5
|> Expect.equal (Err "List too short by 1 element")
]
]
Share your thoughts in the comments below.
P.S. I personally made this error and I found it due to the tests. Tests can still be useful even in a typed functional language.