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?
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.Variable not in scope: a" means?"abcdef"is sugar for['a','b','c','d','e','f']-- you need single quotes to name theChars.ais being rejected an an undefined expression or "variable", but'a'is predefined as a name of a letter.head,tail. These functions will crash your program when the list is empty, so are best to be avoided. Also,length xs == 2will 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 ashead,tail. I wouldn't use it in more "serious" code.