The indentation is indeed wrong, you need to move it at least one column more to the right than the start of elem
, so:
elementAt' :: [a] -> Int -> a
elementAt' xs k = if k < 1 || k > length xs then error "IndexOutOfbound" else elem xs K
where elem xs k
| k == 1 = x
| k > 1 = elem (tail xs) k
But this is not sufficient to make this compile. You furthermore wrote K
instead of k
at the definition of elementAt' xs k = …
, furthermore x
is not defined, so you can use head
, finally you should decrement k
in the recursive call:
elementAt' :: [a] -> Int -> a
elementAt' xs k = if k < 1 || k > length xs then error "IndexOutOfbound" else elem xs k
where elem xs k
| k == 1 = head xs
| k > 1 = elem (tail xs) (k-1)
Now it compiles but still it is not very idiomatic Haskell. You make use of length
for example, which runs in linear time with the length of the list. If the list has infinite length, it will get stuck, furthermore you make use of head
and tail
, and these are non-total functions. Yes, we know that this will always work on a cons
, since otherwise k > length
would be triggered, but regardless it is often batter to use pattern matching over non-total functions.
Therefore a more idiomatic approach is likely:
elementAt' :: [a] -> Int -> a
elementAt' xs k
| k < 1 = error "IndexOutOfBound"
| otherwise = go xs k
where go [] _ = error "IndexOutOfBound"
go (x:xs) i
| i <= 1 = x
| otherwise = go xs (i-1)
Here we know that k
is larger than the length if the list is exhausted, so in the go []
case.
Of course indexing should start at zero, as is documented in EWD831 :).