I'm new to Haskell and I'm trying to write simple functions to get myself used to the syntax, I want to write my own function for adding a certain element to a list at a specific index. Here's what I wrote in Atom (my text editor):
addElem :: a->[a]->Int->[a]
addElem elem list index
| index <= 0 = elem:list
| index < (length list) = a ++ (elem:b) where a = take index list; b = drop index list
| otherwise = list
The idea is that it won't freak out as long as index is an Int
and elem
is of the same type as the elements of list
, but when I try to load this into ghci I get "parse error on `|'." Do I need to constrain the types of the arguments? I'm reading Learn You A Haskell but I haven't gotten to the part where they fully explain how the indentations work, so my error might also be there.
where
blocks need to occur at the end of the whole function, and are shared amongst all the cases. You probably meant to use a let
:
addElem :: a -> [a] -> Int -> [a]
addElem elem list index
| index <= 0 = elem:list
| index < (length list) = let a = take index list; b = drop index list in a ++ (elem:b)
| otherwise = list
Also, note that let
could be written more concisely as let (a,b) = splitAt index list in ...
. splitAt
is also in the Prelude. Of course, you could also just move the where
block to the end of the function (Haskell's laziness makes this easy to reason about).
addElem :: a -> [a] -> Int -> [a]
addElem elem list index
| index <= 0 = elem:list
| index < (length list) = a ++ (elem:b)
| otherwise = list
where
a = take index list
b = drop index list
Personally, I like this less because it suggests that a
and b
may be used elsewhere in the function.
Section 4.4.3 of the 2010 Haskell Report goes into more detail on where where
is allowed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With