0

I'm new to programming and Haskell, so appologies if this is elementary.

I'm having trouble running the program below, but I'm not sure if it's a program error or if I don't know how to use ghci.

I have written a program that behaves likes last, but returns the second to last item in a list instead.

My code is

main :: IO ()
main = return ()    
lastButOne::[a]->a
lastButOne xs = if length xs == 2
                then head xs
                else lastButOne (tail xs)

The program compiles just fine, but I can't seem to find a way to run it without giving me an error.

The textbook gives an example of running a program which emulates drop by doing the following in ghci

ghci> :load myDrop.hs
Ok, modules loaded: Main.
ghci> myDrop 3 "asdfg"
"fg"

However, when I load my lastButOne.hs and attempt to give the program input I get the following

Prelude> :load lastButOne.hs
[1 of 1] Compiling Main             ( lastButOne.hs, interpreted )
Ok, modules loaded: Main.
*Main> lastButOne [a,b,c,d,e,f]

<interactive>:2:13: error: Variable not in scope: a

<interactive>:2:15: error: Variable not in scope: b

<interactive>:2:17: error: Variable not in scope: c

<interactive>:2:19: error: Variable not in scope: d

<interactive>:2:21: error: Variable not in scope: e

<interactive>:2:23: error: Variable not in scope: f

But when I check the type of lastButOne it looks like I'm giving it the correct input type, namely a list:

lastButOne :: [a] -> a

Is there an error in my code or am I trying to use the program incorrectly?

4
  • 2
    Are you trying to provide a string? Then you need to use lastButOne "abcdef". At the moment you are providing a list of variables [a, b, c, d, e ,f] but none of those have been defined anywhere. Commented Jul 26, 2016 at 22:52
  • 2
    What do you think "Variable not in scope: a" means? Commented Jul 26, 2016 at 22:54
  • 1
    Expressed another way: Remember "abcdef" is sugar for ['a','b','c','d','e','f']-- you need single quotes to name the Chars. a is being rejected an an undefined expression or "variable", but 'a' is predefined as a name of a letter. Commented Jul 26, 2016 at 22:56
  • If you are new, I'd recommend that you forget about head,tail. These functions will crash your program when the list is empty, so are best to be avoided. Also, length xs == 2 will scan the whole list, which is quite inefficient when you only need to scan the first 3 elements, at most, to perform the same check. Learn how to use pattern matching instead. E.g. lastButOne [x1,x2] = x1 ; lastButOne (x:xs) = lastButOne xs. Further, note that this function will crash on lists of length 1 or 0, and as such it is as dangerous as head,tail. I wouldn't use it in more "serious" code. Commented Jul 27, 2016 at 7:39

1 Answer 1

3

The problem isn't the type, it's that none of the variables a, b, c, d, e and f exist. You can't use variables that don't exist.

Sign up to request clarification or add additional context in comments.

2 Comments

I see now. I didn't know that the program would interpret a,b,c... as variables, not just characters.
@Zermelo's_Choice If you want characters, surround them with 's. Or just use string literal syntax ("abcdef", which is a shortcut for ['a', 'b', 'c', 'd', 'e', 'f']).