I try to write custom function which take an array and iterate it, i need to print every digit and recursive launch the same function but i get error
parse error on input `main'
code:
firstitem n = if n /= [] n firstitem( tail n )
main = do
print(firstitem [1,2,3])
Your first problem is that you have the wrong syntax for an if
statement. You should write
firstItem n = if {- condition-}
then {- do this -}
else {- do that -}
Second, it's not clear what the function firstItem
is supposed to do. It sounds like it's supposed to return the first item of a list, but your description makes it seem as though you want to iterate over all elements of the list.
You can combine the iteration and printing into a single function like this:
printAll xs = if null xs -- If the list is empty
then return () -- then we're done, so we quit.
else do print (head xs) -- Otherwise, print the first element
printAll (tail xs) -- then print all the other elements.
main = printAll [1,2,3]
The function null
returns True
if the list is empty, otherwise it returns False
. The statement return ()
you can think of as saying "there's nothing more to process, so stop the function now and return no result". The third and fourth lines contain a "do block". The do block is basically a bit of glue that binds the two actions print (head xs)
and printAll (tail xs)
together into one action. You can write it with curly braces to make it a bit clearer:
do {
print (head xs);
printAll (tail xs)
}
although you don't actually need them - the indentation specifies what you mean.
This solves your problem, but it's a bit clunky. Haskell is supposed to be a beautiful language, after all - so let's make your code beautiful! It would be better to use pattern matching to pull the list apart into its head and tail:
printAll [] = return ()
printAll (x:xs) = do print x
printAll xs
That's a lot better. But it could be more modular. Hey, maybe we could make a generic function that takes an action as input, and does that action for every element of the list:
repeatedly f [] = return ()
repeatedly f (x:xs) = do f x
repeatedly f xs
printAll xs = repeatedly print xs
That's neat. But actually, there's already a function that does this. It's called mapM_
(there is a good reason for it being called this, but I won't get into it now) and it's in the Control.Monad
module:
import Control.Monad
printAll xs = mapM_ print xs
Actually, you can leave off the xs
argument, and the compiler can infer that it's supposed to be there:
printAll = mapM_ print
Finally, your code is beautiful. Hope that helps a bit.
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