Problems with function recursion in Haskell

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

Problems with function recursion in Haskell

Henson
Hi,

I'm new in Haskell and I need help in recursion.
That function below is returning "*** Exception: Prelude.head: empty
list" and
I need resolve that:
execNTimes 0 [] = return()
execNTimes n xs = if n<=0  || null xs
     then return()
     else do
         si <- getLine
         let s = words si
             l = read (s !! 1) :: Int
             r = read (s !! 2) :: Int
         if head s=="Q"
             then do
                 let z = slice l r xs
                     m = foldl lcm 1 z
                 print (m `mod` (toInteger 1000000007))
             else do
                 let s1 = update l r xs
                 execNTimes (n-1) s1
         execNTimes (n-1) xs

  Anybody can me help?

Thank you,
Josenildo Silva
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Problems with function recursion in Haskell

Francesco Ariis
On Mon, May 09, 2016 at 10:30:44AM -0300, Henson wrote:

> Hi,
>
> I'm new in Haskell and I need help in recursion.
> That function below is returning "*** Exception: Prelude.head: empty list"
> and
> I need resolve that:
> execNTimes 0 [] = return()
> execNTimes n xs = if n<=0  || null xs
>     then return()
>     else do
>         si <- getLine
>         let s = words si
>             l = read (s !! 1) :: Int
>             r = read (s !! 2) :: Int
>         if head s=="Q"
>             then do
>                 let z = slice l r xs
>                     m = foldl lcm 1 z
>                 print (m `mod` (toInteger 1000000007))
>             else do
>                 let s1 = update l r xs
>                 execNTimes (n-1) s1
>         execNTimes (n-1) xs
>
>  Anybody can me help?

Hello Josenildo,

    the error indeed tells us you are passing an empty list to the function
`head`.

    si <- getLine
        let s = words si
    -- other lines
    if head s == "Q"

so I suppose you are giving an empty string as input to getLine (I cannot
be sure as the code doesn't compile, missing `slice` and `update`).
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Problems with function recursion in Haskell

Sumit Sahrawat, Maths & Computing,
 IIT (BHU)
In reply to this post by Henson
Hi,

Rather than using indexing, or using head, I recommend using pattern matching. These functions are not total, i.e. they fail to provide a valid result for some specific inputs, like head on empty list.

The following is similar to replicateM from Control.Monad, you can either modify it to suit your need, or use replicateM combined with map to turn a list of Strings to a list of IO () as required by replicateM.

    execNTimes :: Int -> [IO ()] -> IO ()
    execNTimes 0 [] = return ()
    execNTimes n (x : xs)
      | n <= 0    = return ()
      | otherwise = x >> execNTimes (n - 1) xs

Where, the following are equivalent:

    a >> b == do a
                 b

Regards,
  Sumit

On 9 May 2016 at 19:00, Henson <[hidden email]> wrote:
Hi,

I'm new in Haskell and I need help in recursion.
That function below is returning "*** Exception: Prelude.head: empty list" and
I need resolve that:
execNTimes 0 [] = return()
execNTimes n xs = if n<=0  || null xs
    then return()
    else do
        si <- getLine
        let s = words si
            l = read (s !! 1) :: Int
            r = read (s !! 2) :: Int
        if head s=="Q"
            then do
                let z = slice l r xs
                    m = foldl lcm 1 z
                print (m `mod` (toInteger 1000000007))
            else do
                let s1 = update l r xs
                execNTimes (n-1) s1
        execNTimes (n-1) xs

 Anybody can me help?

Thank you,
Josenildo Silva
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Problems with function recursion in Haskell

Jonn Mostovoy
In reply to this post by Henson
> Anybody can me help?

Yes, somebody can you help, as long as

 1. You provide enough information on what exactly do you want to
achieve, instead of asking to fix some code;
 2. You specify the input you feed to `getLine`. Top-level arguments
are guarded, while `if head s=="Q"` is not.

If you don't, nobody can you help.

A structure of a good question —

Hello, list.
I want to achieve <a goal>, to do that I came up with <a high-level
solution overview>, which is implemented <a link to the solution
implementation>.
However I encounter <a problem with implementation <debug log with all
the relevant inputs / files> | a problem with high-level solution
<reference to the relevant part of implementation | mention the lack
of implementation>>.
Can you help me with that?

Please note that if your goal is to do a homework it is highly
unlikely that you will find any help in the list or on stackoverflow.
Learning \neq passing a course.

Kindest regards,
¬Σ


On Mon, May 9, 2016 at 4:30 PM, Henson <[hidden email]> wrote:

> Hi,
>
> I'm new in Haskell and I need help in recursion.
> That function below is returning "*** Exception: Prelude.head: empty list"
> and
> I need resolve that:
> execNTimes 0 [] = return()
> execNTimes n xs = if n<=0  || null xs
>     then return()
>     else do
>         si <- getLine
>         let s = words si
>             l = read (s !! 1) :: Int
>             r = read (s !! 2) :: Int
>         if head s=="Q"
>             then do
>                 let z = slice l r xs
>                     m = foldl lcm 1 z
>                 print (m `mod` (toInteger 1000000007))
>             else do
>                 let s1 = update l r xs
>                 execNTimes (n-1) s1
>         execNTimes (n-1) xs
>
>  Anybody can me help?
>
> Thank you,
> Josenildo Silva
> _______________________________________________
> Haskell-Cafe mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Problems with function recursion in Haskell

Jonne Ransijn
In reply to this post by Henson

Hi Josenildo.

I would personally rewrite your code to something like this:

import Data.Maybe (fromMaybe)
import System.IO (hFlush, stdout)
import Text.Read (readMaybe)

readDef :: a -> String -> a
readDef def = fromMaybe def . readMaybe

isAtLeast :: [a] -> Int -> Bool
isAtLeast ls n
    | n <= 0  = True
    | null ls = False
    | otherwise = isAtLeast ls (n-1)

execNTimes :: Int -> [a] -> IO ()
execNTimes n lst
    | n <= 0 = return()
    | do
        (from, to, quit) <- getCmds
        if quit
            then let z = slice from to xs
                     m = foldl lcm 1 z in
                print $ m `mod` modVal
            else execNTimes (n-1) $ update from to lst
        execNTimes (n-1) lst
  where
    modVal :: Integer
    modVal = 1000000007
    getCmds :: IO (Int, Int, Bool)
    getCmds = do
        putStr "Enter command: "
        hFlush stdout
        cmds <- words <$> getLine
        if not $ cmds `isAtLeast` 3
            then do
                putStrLn "Too few commands"
                getCmds
            else let from = readDef 0 (cmds !! 1) :: Int
                     to   = readDef 0 (cmds !! 2) :: Int
                     quit = head cmds == "Q" in
                if from < 0 || to >= length lst || from > to
                    then do
                        putStrLn "Invalid range"
                        getCmds
                     else (from, to, quit)

Do note that the above code is untested, and that it's written on a mobile phone.

I don't know what your intentions with the code are, so I added some error messages and variable names that you might want to change.

About 'xs':
xs is frequently used to mean "rest of list". I would recommend using ls or lst instead to name the whole list.


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Problems with function recursion in Haskell

Jonne Ransijn

Whoops, isAtLeast should be

    | otherwise = isAtLeast (tail ls) (n-1)


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Problems with function recursion in Haskell

Johannes Waldmann-2
In reply to this post by Henson
> ... homework  ... it is highly unlikely that you will
> find any help in the list or on stackoverflow.

Quite often students do find homework "help" on stackoverflow.
Of course SO will do nothing to discourage that.
I'm not saying they should delete homework questions outright,
but if they'd want quality, they'd introduce a "homework" tag
so that these questions can be avoided more easily
by people who would want to use SO to read/write quality
answers/questions. But it seems that SO's goal is mostly
numbers, that is, users. Actually, viewers for the job ads.
And as long as the advertisers are paying ...

Anyway, back to Haskell (but not leaving rant mode):
the code example in the  original question,
although being rather short, manages to showcase several features
that should be avoided in introductory teaching:
numbers, lists, strings, and IO. (*)

But, perhaps the instructor had a specific motivation.
We can only guess, and that is why the recommended way
for getting help with homework is (in that order):
pay attention in class, then work on the exercises on your own,
then with fellow students, and with the remaining questions,
go to your instructor.

- J.W.

(*) and, recently, we should also avoid tuples
https://mail.haskell.org/pipermail/libraries/2016-February/026678.html
(I like the "matlab league" characterisation)
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Problems with function recursion in Haskell

Chris Smith-31
In reply to this post by Henson
On Mon, May 9, 2016 at 6:30 AM, Henson <[hidden email]> wrote:
execNTimes 0 [] = return()
execNTimes n xs = if n<=0  || null xs
    then return()
    else do
        si <- getLine
        let s = words si
            l = read (s !! 1) :: Int
            r = read (s !! 2) :: Int
        if head s=="Q"
            then do
                let z = slice l r xs
                    m = foldl lcm 1 z
                print (m `mod` (toInteger 1000000007))
            else do
                let s1 = update l r xs
                execNTimes (n-1) s1
        execNTimes (n-1) xs

Your code is making the assumption that (words si)  is non-empty.  When that's not true, such as when the input from the console is empty, your program will crash at the use of `head`, since it throws an error when applied to an empty list.  That's what you are seeing.  Incidentally, by using `l` and `r` later on, you're also assuming that the input contains at least 2 more words after that first one.  Violating that will also crash your program.  Finally, your use of `read` means that the program will crash if the second two inputs are not numbers.  All three of these functions should be used with great caution, or not at all, since they threaten to crash your program!

Here's a very concise way to write this, using pattern guards:

    case words si of
        [ a, ls, rs ]
            , Right l <- readEither ls :: Either String Int
            , Right r <- readEither rs :: Either String Int
            -> if a == "Q"
                    then do
                        let x = slice l r xs
                        let m = foldl lcm 1 z
                        print (m `mod` (toInteger 1000000007))
                    else do
                        let s1 = update l r xs
                        execNTimes (n-1) s1
        _ -> putStrLn "Invalid input."

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Haskell Better Editor

Henson
In reply to this post by Henson
Friends,

What's the better text editor for Haskell development?
More productive and more rapid learning curve?
Any trick for initiating in haskell and rapid advance?
Please let your comments.

Thank you,
Josenildo
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Haskell Better Editor

Wojciech Danilo
Try atom. The only editors with better support are vim and emacs.
On Fri, 13 May 2016 at 20:47, Henson <[hidden email]> wrote:
Friends,

What's the better text editor for Haskell development?
More productive and more rapid learning curve?
Any trick for initiating in haskell and rapid advance?
Please let your comments.

Thank you,
Josenildo
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Haskell Better Editor

Joseph Melfi
I’d go with Atom.  Good support for syntax and stack or cabal environment setups.

Joseph Melfi

On Fri, May 13, 2016 at 12:26 PM Wojciech Danilo <">Wojciech Danilo > wrote:
Try atom. The only editors with better support are vim and emacs.
On Fri, 13 May 2016 at 20:47, Henson <[hidden email]> wrote:
Friends,

What's the better text editor for Haskell development?
More productive and more rapid learning curve?
Any trick for initiating in haskell and rapid advance?
Please let your comments.

Thank you,
Josenildo
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe



_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Haskell Better Editor

David Feuer
In reply to this post by Henson

Much as I hate emacs, I have to admit it is a pretty awesome Haskell development environment once you get it set up right.

On May 13, 2016 2:47 PM, "Henson" <[hidden email]> wrote:
Friends,

What's the better text editor for Haskell development?
More productive and more rapid learning curve?
Any trick for initiating in haskell and rapid advance?
Please let your comments.

Thank you,
Josenildo
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Haskell Better Editor

Alexander Kjeldaas
For the emacs route, do try spacemacs as the default emacs setup has no batteries included, and a rather large manual needed for assembly.

On Fri, May 13, 2016 at 9:55 PM, David Feuer <[hidden email]> wrote:

Much as I hate emacs, I have to admit it is a pretty awesome Haskell development environment once you get it set up right.

On May 13, 2016 2:47 PM, "Henson" <[hidden email]> wrote:
Friends,

What's the better text editor for Haskell development?
More productive and more rapid learning curve?
Any trick for initiating in haskell and rapid advance?
Please let your comments.

Thank you,
Josenildo
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe



_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Haskell Better Editor

Marcin Mrotek
Hello,

>I'm using ViM with that started material:
>http://www.stephendiehl.com/posts/vim_2016.html
>If exist any better that inform please.

Eh, sorry, I think I've responded only to you instead of the whole group. Anyway, I'm using Atom, and while I don't actually "like" this editor (in fact, I find it very annoying, with slow loading times on a 4 core processor, and occasional white screen of death on Windows) I still think it's the best of the ones I've tried (vim, emacs + evil mode, leksah).

Best regards,
Marcin Mrotek

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Haskell Better Editor

Manuel Gómez
On Fri, May 13, 2016 at 5:47 PM, Marcin Mrotek
<[hidden email]> wrote:

> Hello,
>
>>I'm using ViM with that started material:
>>http://www.stephendiehl.com/posts/vim_2016.html
>>If exist any better that inform please.
>
> Eh, sorry, I think I've responded only to you instead of the whole group.
> Anyway, I'm using Atom, and while I don't actually "like" this editor (in
> fact, I find it very annoying, with slow loading times on a 4 core
> processor, and occasional white screen of death on Windows) I still think
> it's the best of the ones I've tried (vim, emacs + evil mode, leksah).

Not sure who asked about Vim, but there’s
https://github.com/begriffs/haskell-vim-now
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe