On Mon, May 9, 2016 at 6:30 AM, Henson <jfsihenson@gmail.com> 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."