I'm learning Haskell and I wanted to do a function where it receives two numbers and it intercalates between positive and negative. Thanks for your help. example:
intercalarNum 5 2 = [2,-2,2,-2,2]
Tried to do it many ways but ghci says it has a error everytime so I dont know what do do anymore
intercalarNum :: (Num a , Ord a ) => a -> a -> [a]
intercalarNum 0 y = []
intercalarNum x y = y : intercalarnumAux (intercalarNum (x-1) y)
intercalarnumAux :: (Num a , Ord a ) => a -> a
intercalarnumAux x | x < 0 = -x
| x > 0 = -x
| x == 0 = 0
Let's start form this part:
intercalarnumAux :: (Num a , Ord a ) => a -> a
intercalarnumAux x | x < 0 = -x
| x > 0 = -x
| x == 0 = 0
Now, that very last 0
can also be written as -0
, and since x==0
, that can also be written as -x
. If we choose to do that, we get
intercalarnumAux :: (Num a , Ord a ) => a -> a
intercalarnumAux x | x < 0 = -x
| x > 0 = -x
| x == 0 = -x
hence we discover that the result is -x
in all cases! We could simply write
intercalarnumAux :: (Num a , Ord a ) => a -> a
intercalarnumAux x = -x
or even
intercalarnumAux :: (Num a) => a -> a
intercalarnumAux x = -x
We could also not define this function at all, and simply use uniry minus (aka negation) - ....
as needed.
Now, let's examine the main routine:
intercalarNum :: (Num a , Ord a ) => a -> a -> [a]
intercalarNum 0 y = []
intercalarNum x y = y : intercalarnumAux (intercalarNum (x-1) y)
This actually looks rather good. While it is still wrong as you discovered trying to compile it, it gets most things correct.
The base case where the first argument is 0
is correct.
The inductive case starts the output list as y : ...
, which is correct.
It also decrements x
in the recursive call, passing x-1
which is correct.
Now, there is one last thing to fix. You are very close, so let me give you a hint. Right now you call intercalarnumAux (intercalarNum (x-1) y)
which means - (intercalarNum (x-1) y)
but you can't negate a list like that. Try to negate a number instead. Well, don't negate x-1
since decrementing that is correct. Can you spot some other number to negate? Just remember to use parentheses as in (- somethingToNegateHere)
, otherwise the minus sign could be interpreted as binary subtraction.