I am trying to declare a function in Haskell GHCi as
fact :: Int -> Int
But I am getting this error - error: parse error on input `->'
I do not understand why this is happening. Can anyone please explain it to me? Thanks.
First off, it looks like you're using a pretty old version of GHC. In newer versions, the GHCi syntax has been relaxed a bit.
But still: what you type in GHCi does not have the same rules as what you write in a Haskell source file. Specifically, the GHCi prompt is essentially an IO monad chain evaluator, the reason being that you can write stuff like
Prelude> putStrLn "Hello"
Hello
or
Prelude> readFile "test.txt"
"fubar\nbaz"
and actually have it execute right there. By contrast, in a Haskell source file, you only declare bindings, and these can then be invoked in the main action or a GHCi session.
But in this case, you want to declare a binding within GHCi itself. You can do that too, but it's a bit awkward, basically you need to start with let and then squeeze everything in a single line:
Prelude> let fact :: Int -> Int; fact n = product [1..n]
Actually, newer GHCi version allow you to omit the let, and you can have multiple-line definitions by using a special bracket syntax:
Prelude> :{
Prelude| fact :: Int -> Int
Prelude| fact n = product [1..n]
Prelude| :}
but I would recommend against this. If you actually have some bigger definitions, better put them in a proper Haskell source and load that into GHCi.
Related
I have many files that must be processed automatically. Each file holds the response of one student to an exercise which asks the student to give definitions for some functions given a type for each function.
My idea is to have an Haskell script that loads each student file, and verifies if each function has the expected type.
A constraint is that the student files are not defined as modules.
How can I do this?
My best alternative so far is to spawn a GHCi process that will read stdin from a "test file" with GHCi commands, for example:
:load student1.hs
:t g
... and so on ...
then parse the returned output from GHCi to find the types of the functions in the student file.
Is there another clean way to load an arbitrary Haskell file and introspect its code?
Thanks
Haskell does not save type information at runtime. In Haskell, types are used for pre-runtime type checking at the static analysis phase and are later erased. You can read more about Haskell's type system here.
Is there a reason you want to know the type of a function at runtime? maybe we can help with the problem itself :)
Edit based on your 2nd edit:
I don't have a good solution for you, but here is one idea that might work:
Run a script that for each student module will:
Take the name of the module and produce a file Test.hs:
module Test where
import [module-name]
test :: a -> b -> [(b,a)]
test = g
run ghc -fno-code Test.hs
check the output does not contain type errors
write results into a log file
I think if you have a dynamically determined number of .hs files, which you need to load, parse and introspect, you could/should use the GHC API instead.
See for example:
Using GHC API to compile Haskell sources to CORE and CORE to binary
https://mail.haskell.org/pipermail/haskell-cafe/2009-April/060705.html
These might not be something you can use directly — and I haven't done anything like this myself so far either — but these should get you started.
See also:
https://wiki.haskell.org/GHC/As_a_library
https://hackage.haskell.org/package/hint
The closest Haskell feature to that is Data.Typeable.typeOf. Here's a GHCi session:
> import Data.Typeable
> typeOf (undefined :: Int -> Char)
Int -> Char
> typeOf (undefined :: Int -> [Char])
Int -> [Char]
> typeOf (undefined :: Int -> Maybe [Char])
Int -> Maybe [Char]
> :t typeOf
typeOf :: Typeable a => a -> TypeRep
Under the hood, the Typeable a constraint forces Haskell to retain some type tags until runtime, so that they can be retrieved by typeOf. Normally, no such tags exist at runtime. The TypeRep type above is the type for such tags.
That being said, having such information is almost never needed in Haskell. If you are using typeOf to implement something, you are likely doing it wrong.
If you are using that to defer type checks to run time, when they could have been performed at compile time, e.g. using a Dynamic-like type for everything, then you are definitely doing it wrong.
If the function is supposed to be exported with a specific name, I think probably the easiest way would be to just write a test script that calls the functions and checks they return the right results. If the test script doesn't compile, the student's submission is incorrect.
The alternative is to use either the GHC API (kinda hard), or play with Template Haskell (simpler, but still not that simple).
Yet another possibility is to load the student's code into GHCi and use the :browse command to dump out everything that's exported. You can then grep for the term you're interested in. That should be quite easy to automate.
There's a catch, however: foo :: x -> x and foo :: a -> a are the same type, even though textually they don't match at all. You might contemplate trying to normalise the variable names, but it's worse: foo :: Int -> Int and foo :: Num x => x -> x don't look remotely the same, yet one type is an instance of the other.
...which I guess means I'm saying that my answer is bad? :-(
I've recently come across a bot on Twitter named EmojiHaskell, that claims to tweet 'interpretable Haskell code with emoji variable names'. A particular Tweet caught my attention, as it looked like malformed syntax to me, so I decided to take a closer look. So far I've produced the following code:
module Main where
🙏 :: [🍳] -> Maybe 🍳
🙏 [] = Nothing
🙏 (👽:as) = Just 👽
main = print $ 🙏 "♥"
Since I've used λ on occasion in my Haskell code, I expected this code to work, but it appears that GHC doesn't like the emoji at all.
With $ runhaskell Main.hs I get:
Main.hs:4:1: parse error on input ‘🙏’
I've already had a look at the UnicodeSyntax extension,
and tried to only use some or single emoji instead of all of them to see if a certain one provokes the problem.
Now my question is this:
Is there currently a Haskell compiler that would accept the code?
Can I get GHC to work with this code somehow?
That code is not valid haskell. The reason is that 🙏 (like, probably, all Emojis) is a symbol character:
Prelude> import Data.Char
Prelude Data.Char> generalCategory '🙏'
OtherSymbol
But you can still use them like any other symbol, namely as an operator:
Prelude Data.Char> let (🙏) = (+)
Prelude Data.Char> 32 🙏 42
74
Furthermore, as user3237465 pointed out, if you use the prefix syntax for operators, i.e. put it in parentheses, you can even use it like any other symbol:
(🙏) :: [a] -> Maybe a
(🙏) [] = Nothing
(🙏) ((👽):as) = Just (👽)
main = print $ (🙏) "♥"
This is almost the example in the original post. Unfortunately, this trick does not work for the type variable. The the documentation is worded a bit unfortunately, but in fact symbols are never type variables and always type constructors
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.
I'm beginning Haskell... I tried to write the following trivial function in two different ways, letting Haskell decide the types, and the type system does something different in each case. What is the explanation for that behavior?
Prelude> let f x = 2 * x
Prelude> let g = (2*)
Prelude> :info f
f :: Num a => a -> a -- Defined at <interactive>:1:5
Prelude> :info g
g :: Integer -> Integer -- Defined at <interactive>:1:5
Thanks!
This is known as the monomorphism restriction.
Basically, it means that top-level bindings that look like x = are forced to be non-polymorphic, unless you specify a type signature. Bindings with arguments, i.e. f x = are not affected. See the link for details as to why this restriction exists.
Usually, you get an error message when the restriction is applied, but in this case GHCi is able to use type defaulting to change the type Num a => a to Integer.
The easiest way to dodge it is to either use an explicit type signature, or put
{-# LANGUAGE NoMonomorphismRestriction #-}
at the top of your module, or run GHCi with -XNoMonomorphismRestriction.
As others have pointed out, this is caused by something called the "Monomorphism Restriction".
MR can be useful for writers of Haskell compilers, and there is controversy about whether or not it is worthwhile to have in the language in general. But there is one thing everyone agrees: at the GHCi prompt, MR is nothing but a nuisance.
MR will probably be turned off by default in this context in an upcoming version of GHC. For now, you should disable it in GHCi by creating a text file called ".ghci" in your home directory that contains a line like this:
:set -XNoMonomorphismRestriction
Because the definition of g doesn't explicitly name its arguments, you run into the monomorphism restriction, preventing g from being polymorphic and (in this case) causing GHC to default to Integer.
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.