Reputation: 24535
I want to write a function which prints out a list of numbers from 1 to n: [1,2,...n], I know it can be done by [1..n]
but I want to make my own function:
addtimes n = addtimes_ [] n
addtimes_ [lst] a =
if a < 1
then [lst]
else addtimes_ [a:lst] (a-1)
main =
print $ addtimes 10
Though above code compiles and runs, it gives following runtime error:
testing: testing.hs:(3,1)-(6,37): Non-exhaustive patterns in function addtimes_
Where is the problem and how can it be solved?
Upvotes: 1
Views: 90
Reputation: 18249
See the following, with corrected syntax (and type signatures added, seriously these are essential for both code documentation and for better error messages):
addtimes :: (Num a, Ord a) => a -> [a]
addtimes n = addtimes_ [] n
addtimes_ :: (Num a, Ord a) => [a] -> a -> [a]
addtimes_ lst a =
if a < 1
then lst
else addtimes_ (a:lst) (a-1)
main :: IO ()
main =
print $ addtimes 10
As well as referring to [lst]
(a singleton list containing the one element lst
) instead of lst
(which can refer to anything, which in the context of your function must be a list, but can be of any length), you had put [a:lst]
(again a singleton list, this time containing a list) instead of (a:lst)
, a list made up of first element a
appended to the front of lst
. (The parentheses are not needed for any syntactic reason, but are usually needed in practice, as in the above code, because of operator precedence: addtimes_ a:list (a-1)
would be parsed as (addtimes_ a):(list (a-1))
, which definitely isn't what you mean.
Upvotes: 5
Reputation: 16224
Edit:
To achieve what you want, now I understand your goal reading your
addtimes :: Int -> [Int]
addtimes 0 = []
addtimes n = if n > 0
then addtimes_ 1 n
else error "Doesn't work with negatives"
addtimes_ :: Int -> Int -> [Int]
addtimes_ m n = if n > m
then m : (addtimes_ (m+1) n)
else [n]
main =
print $ addtimes (10)
That will create a list with the numbers adding 1 consecutively
[1,2,3,4,5,6,7,8,9,10]
Upvotes: 1