Haskell functions in GHCi - haskell

I am completely new to Haskell. I have been trying to learn how to write functions, lets say to add two integer numbers. I am currently using GHCi to code Haskell. I tried learning from http://www.haskell.org/tutorial/functions.html, however this does not work, I get a not in scope error. I greatly appreciate any help with this. Am I supposed to not use GHCi to code haskell in order to create functions? GHCi, seems to work okay so far, for everything other than functions.
Many thanks in advance.

You have to use let to declare functions in GHCI
ghci>let add x y = x + y
ghci>add 3 3
6
In general though I would advice you to open up a text editor and write your functions in there, save as .hs and open it with :l in ghci
Like this ( from RWH)
-- file: ch03/add.hs
add a b = a + b
Then:
ghci> :l add.hs
[1 of 1] Compiling Main ( add.hs, interpreted )
Ok, modules loaded: Main.
ghci> add 1 2
3

Related

Why is my Haskell code saying 'variable not in scope: main'?

When I type the following in the interactive shell of Haskell on the repl.it website, it works perfectly.
let squareMe x = x * x
let myFruit = ["banana", "apple", "kiwi", "orange"]
But when I type it into a source file and click 'Run' I get the error:
<interactive>:3:1: error:
• Variable not in scope: main
• Perhaps you meant ‘min’ (imported from Prelude)
I've been trying to understand this error and come up with a solution for a couple of hours now and am no nearer to finding a solution or understanding what the error means.
The Haskell REPL (GHCi) and actual Haskell programs are considerably different.
The reasons for this difference is the goal of the two formats. Firstly, GHCi is a testing area, not a code-running area. However, Haskell source files are meant to run a certain process, which is named main. When you run a source file, the Haskell compiler (usually GHC) looks for the IO action called main, and tries to run it. In this case, there was no main, so it failed.
Secondly, what you typed is not a valid Haskell program, those are declarations that would be fine in GHCi, but not in Haskell source. This would be correct in a source file:
squareMe x = x * x
myFruit = ["banana", "apple", "kiwi", "orange"]
Note the lack of let; Haskell source files don't use it to declare things.
Note that on repl.it, this will still complain that main is missing, but you can then refer to squareMe and myFruit in the REPL without worry. In other words, the error will still appear, but it doesn't matter, because you can use whatever you wrote in the file nonetheless.
If you wanted to suppress the warning, you could write the lines:
main :: IO () -- This says that main is an IO action.
main = return () -- This tells main to do nothing.
There are many things you could have the program do instead of this. Here are a couple of examples:
main = putStrLn "No errors!" Will print No errors! when you run it.
main = print myFruit Will print ["banana", "apple", "kiwi", "orange"] when you run it.
Please note that this answer applies mostly to the site repl.it specifically, though in general this is how Haskell programs are structured.
If you compile a Haskell source there needs to be a main symbol as entry point, just like when compiling e.g. a C program. Also in a compiled file you must skip the lets. E.g.
squareMe x = x * x
main = putStrLn . show $ squareMe 4
If what you’re writing is more like a library or a set of utility routines than a complete program, you can declare it as a module. Then GHC will compile it to an object you can link to other programs, and you can also load it in GHCI. It will not be expected to contain a main routine.
If you save this to a .hs file:
module Example (squareMe) where
squareMe x = x * x -- Exported to other modules.
myFruit = ["banana", "apple", "kiwi", "orange"] -- Not exported.
Compiling this with GHC will give you a .hi file and a .o file, and running it in GHCI will give you this:
GHCi, version 8.0.2: http://www.haskell.org/ghc/ :? for help
Ok, modules loaded: Example (sx-modulexmpl.o).
Prelude Example> squareMe 2
4
You can also compute an expression that references a library from the command line. ghc -e "squareMe 2" Example.hs prints 4.

How to load a script to ghci?

I'm just starting learning Haskell, and having a hard time understanding the 'flow' of a Haskell program.
For example in Python, I can write a script, load it to the interpreter and see the results:
def cube(x):
return x*x*x
print cube(1)
print cube(2)
print cube(cube(5))
# etc...
In Haskell I can do this:
cube x = x*x*x
main = print (cube 5)
Load it with runhaskell and it will print 125.
Or I could use ghci and manually type all functions I want to test
But what I want is to use my text editor , write a couple of functions , a few tests , and have Haskell print back some results:
-- Compile this part
cube x = x*x*x
-- evaluate this part:
cube 1
cube 2
cube (cube 3)
--etc..
Is something like this possible?
Very possible!
$ ghci
> :l filename.hs
That will load the file, and then you can use the functions directly.
> :r
That will cause the file to be reloaded after you make an edit. No need to mention the file, it will reload whatever the last one you loaded was. This also will work if you do ghci filename.hs initially instead of :l.
cube x = x*x*x
main = do
print $ cube 1
print $ cube 2
print $ cube (cube 3)
$ ghci cube.hs
...
ghci> main
See the GHCI user guide.
I also highly recommend checking out the QuickCheck library.
You'll be amazed at how awesome testing can be with it.
To load a Haskell source file into GHCi, use the :load command
cf Loading source file in Haskell documentation

Haskell error parse error on input `='

I'm new to Haskell and after starting ghci I tried:
f x = 2 * x
and I obtained:
<interactive>:1:4: parse error on input `='
which I don't understand.
Strangely, it worked well before. I suppose that I have done misconfigured Haskell. Reinstalling ghc6 doesn't solve the problem.
For information, I use Ubuntu 10.4 and the version of ghc6 is 6.12.1-12
In GHCi 7.x or below, you need a let to define things in it.
Prelude> let f x = x * 2
Prelude> f 4
8
Starting from GHC 8.0.1, top-level bindings are supported in GHCi, so OP's code will work without change.
GHCi, version 8.0.1.20161213: http://www.haskell.org/ghc/ :? for help
Prelude> f x = x * 2
Prelude> f 4
8
When you type into a Haskell source file,
f x = 2 * x
is correct.
When you type directly into ghci, you need to type let at the start of the line:
let f x = 2 * x
A good rule of thumb for using ghci is that any code you enter should conform to do-block semantics; that is, you could assume syntactically that you're programming within the IO monad (if this is new terminology, don't worry! I'd highly recommend reading through this tutorial).
This answer illustrates this point with an example, and may provide more working insight into the nature of IO and ghci.
Starting in GHC 8.0.1 this would no longer generate an error.

Functions in Haskell

I'm new to functional programming. I have a basic question.
I'm using the Hugs interpreter,
I would like to write a function in Haskell; I went though several tutorials, but I'm not getting it.
fact :: Int -> Int
fact n = if n == 0 then
1
else
n * fact (n-1)
This gives me a syntax error :-S
ERROR - Syntax error in input (unexpected `=')
I assume you type this right into the interactive prompt. Sadly, these are relatively primitive in Haskell - complex definitions, such as fact, can't be entered at the prompt, at least not in the same way you'd normally write them.
You need to put function definitions etc. into modules, then load those via (e.g.) :load fact.hs. There are resources for Hugs specifically that provide more information on this and other topic (I used http://cvs.haskell.org/Hugs/pages/hugsman/index.html to check my assumptions).
Also note that indentation matters, so the code won't work the way you posted it here even when in a module. Those tutorials will have correct versions. If not, they're useless and you should forget them.
The syntax is incorrect. In Haskell, whitespace matters, much like it does in Python. More specifically, if you have text that starts on the first column of a line, the interpreter will think it's a top-level declaration. The correct syntax would be (for example):
fact :: Int -> Int
fact n = if n == 0
then 1
else n * fact (n-1)
You could also put the if in one line if you'd like to. So if you're using an interactive prompt you could do:
λ> let fact n = if n == 0 then 1 else n * fact (n-1)
Notice that you'll need to use let in order to define functions on the prompt (at least this is how it's done in GHCi, I'm not sure about Hugs). You'll be better off putting them in a separate file and then loading that in the interpreter. But anyway, a much nicer solution would use pattern-matching in my opinion anyway:
fact :: Int -> Int
fact 0 = 1
fact n = n * fact (n-1)
Here, the interpreter would pattern-match the first argument of the function against the possible cases listed. So if the first argument is null, the result if 1, otherwise apply the function recursively.
Create a file named, for example, fact.hs
-- copying cedric's nicely formatted code
fact :: Int -> Int
fact n = if n == 0
then 1
else n * fact (n-1)
That's all that really needs to be there. When you want to make real modules, you should do some extra stuff.
Now, open up ghci from the same folder. At the ghci prompt, use the :l command to load the "module"
Prelude> :l fact.hs
[1 of 1] Compiling Main ( fact.hs, interpreted )
Ok, modules loaded: Main.
*Main> fact 3
6
*Main> fact 10
3628800
I assume it's a very similar process with Hugs. I think hugs requires the file name to be capitalized. ghci simply creates a "Main" module and puts your code in it; that's why the prompt changes from Prelude> to *Main>
When I work on small Haskell functions, I usually keep two terminals open: one for vim and one for ghci. When I change the file in vim (and save it), I just use :r in ghci to reload the new definitions.
*Main> :r
Ok, modules loaded: Main.
It should be mentioned that the most elegant way to write this function is:
fac n = product [1..n]
See http://www.willamette.edu/~fruehr/haskell/evolution.html for details.

Haskell modules: hidden names and ghci

I'm trying to export just a subset of names from a Haskell module, but ghci happily lets me access even the hidden names.
module Hiding (shown, calc) where
calc = shown * hidden
shown :: Int
shown = 3
hidden :: Int
hidden = 2
But when trying this in ghci I get:
Prelude> :l Hiding.hs
[1 of 1] Compiling Hiding ( Hiding.hs, interpreted )
Ok, modules loaded: Hiding.
*Hiding> hidden
2
What am I doing wrong?
(Edit: for what it's worth, I'm using ghci 6.12.3 on Arch Linux)
It looks like GHCi is loading your module for you to inspect it, i.e. putting you in the scope of the module. Two hints at that are the prompt *Hiding> and the fact that you accessed the hidden function.
Edit:
End there it is: http://www.haskell.org/ghc/docs/latest/html/users_guide/interactive-evaluation.html#id3045728
It looks to me like you've done the right thing. If you attempt to reference that module from another module I'll bet hidden refuses to work. Could be that GHCI is all-knowing :)

Resources