Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell, how to print value and return in function

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])
like image 783
testCoder Avatar asked Dec 16 '22 18:12

testCoder


1 Answers

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.

like image 94
Chris Taylor Avatar answered Jan 04 '23 22:01

Chris Taylor