a very simple question from a Haskell learner. I am working through Yet Another Haskell Tutorial and I am stuck on a simple syntax practice. The code given below: When I copy and paste it (from pdf) and then adjust the indentation it works fine, but when I type it out into an editor (in my case Notepad++) then it throws the following error:
Guess.hs:8:9: parse error on input ´hSetBuffering´
I made sure that I did not mix tabs and whitespaces (4 whitespaces) and I did not find a typo in the book. I am sure it is a very simple mistake so thanks for any input.
Nebelhom
Here is the code:
module Main
where
import IO
import Random
main = do
hSetBuffering stdin LineBuffering
num <- randomRIO (1::Int, 100)
putStrLn "I'm thinking of a number between 1 and 100"
doGuessing num
doGuessing num = do
putStrLn "Enter your guess:"
guess <- getLine
let guessNum = read guess
if guessNum < num
then do putStrLn "Too low!"
doGuessing num
else if read guess > num
then do putStrLn "Too high!"
doGuessing num
else do putStrLn "You Win!"
There's no syntax error that I can see, or reproduce:
$ ghci A.hs
GHCi, version 7.0.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
[1 of 1] Compiling Main ( A.hs, interpreted )
Ok, modules loaded: Main.
which means it is probably tabs. Did you insert a tab somewhere? And then use 4 spaces for indenting? Tabs are in general a bad idea in Haskell, as they lead to unintentional, and unintelligible, syntax errors.
Related
I created a new quick.hs file in the ghci.exe directory. And the content is
quicksort::(Ord a)=>[a]->[a]
quicksort []=[]
quicksort (x:xs)=
let smaller = [a |a<-xs,a<=x]
larger = [a |a<-xs,a>x]
in quicksort smaller ++ [x] ++ quicksort larger
When I issue :l quick in the ghci command lline, the output is
Prelude> :l quick
[1 of 1] Compiling Main ( quick.hs, interpreted )
quick.hs:5:17: error:
parse error on input ‘=’
Perhaps you need a 'let' in a 'do' block?
e.g. 'let x = 5' instead of 'x = 5'
Failed, modules loaded: none.
I have concured this kind of problems many times. What's wrong on earth?
You say in the comments that you are sure there are no tab characters in the source file, but inspecting the source of your question, indeed there is one right before the in token. Replace that with the appropriate number of spaces and you'll be all good.
You have to remove all tabs and change it by spaces. I hope that this instruction helps you.
If I have a project structured like this:
project/
src/
Foo.hs
Bar.hs
With files Foo.hs:
module Foo where
foo :: String
foo = "foo"
and Bar.hs:
module Bar where
import Foo
bar :: String
bar = foo ++ "bar"
If my current directory is src, and I enter ghci and run :l Bar.hs, I get the expected output:
[1 of 2] Compiling Foo ( Foo.hs, interpreted )
[2 of 2] Compiling Bar ( Bar.hs, interpreted )
Ok, modules loaded: Bar, Foo.
But if I move up to the project directory (which is where I'd prefer to stay and run vim/ghci/whatever), and try :l src/Bar.hs, I get:
src/Bar.hs:3:8:
Could not find module ‘Foo’
Use -v to see a list of the files searched for.
Failed, modules loaded: none.
Why does ghc not search for Foo in the same directory as Bar? Can I make it do so? And can I propagate that change up to ghc-mod and then to ghcmod.vim? Because I get errors about can't find module when I'm running my syntax checker or ghc-mod type checker in vim.
I'm running ghc 7.10.1.
The flag you're looking for is -i<dir>:
% ghci --help
Usage:
ghci [command-line-options-and-input-files]
...
In addition, ghci accepts most of the command-line options that plain
GHC does. Some of the options that are commonly used are:
-i<dir> Search for imported modules in the directory <dir>.
For example
% ls src
Bar.hs Foo.hs
% ghci -isrc
GHCi, version 7.8.2: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
λ :l Foo
[1 of 1] Compiling Foo ( src/Foo.hs, interpreted )
Ok, modules loaded: Foo.
λ :l Bar
[1 of 2] Compiling Foo ( src/Foo.hs, interpreted )
[2 of 2] Compiling Bar ( src/Bar.hs, interpreted )
Ok, modules loaded: Foo, Bar.
You can also pass ghc-mod the -i<dir> flag from within ghcmod.vim
If you'd like to give GHC options, set g:ghcmod_ghc_options.
let g:ghcmod_ghc_options = ['-idir1', '-idir2']
Also, there's buffer-local version b:ghcmod_ghc_options.
autocmd BufRead,BufNewFile ~/.xmonad/* call s:add_xmonad_path()
function! s:add_xmonad_path()
if !exists('b:ghcmod_ghc_options')
let b:ghcmod_ghc_options = []
endif
call add(b:ghcmod_ghc_options, '-i' . expand('~/.xmonad/lib'))
endfunction
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm fairly new to Haskell. I've been trying to create a utility to count the number of words and lines in Haskell for a few days to help me understand the language better. However, I'm struggling to get it working.
So far, I have:
wordCountUtility = do
putStrLn "Please enter the filename:"
filename <- getLine
putStrLn ("The file name you have entered is: " ++ filename)
contents <- readFile filename -- read the file specified in “name” into “contents”
lower <- (return . map toLower) contents
putStrLn lower
I have tried to use 'chop' and found print . length . words =<< getContents and have modified it a number of times, but I have had no luck.
I've also had a look at quite a few similar answers on Stack Overflow, such as : identifying number of words in a paragraph using haskell
The output should be somewhat similar to this:
Amount of Lines within the file
Lines : 10
Amount of Words found within the file
Words : 110
Any help would be much appreciated.
Your wordCountUtility should probably be not be counting words yet. You should just stop at something like
commandLineUtility :: (String -> String) -> IO ()
commandLineUtility fn = do
putStrLn "Please enter the filename:"
filename <- getLine
putStrLn ("The file name you have entered is: " ++ filename)
contents <- readFile filename -- read the file specified in “name” into “contents”
lower <- (return . fn) contents
putStrLn lower
(I am keeping this as close to your text as possible.) Now, though, you have to figure out what
(String -> String) function you want to apply. This is a pure function and should be developed separately. So you might write:
cwlcount :: String -> (Int, Int, Int)
cwlcount str = (length str, length (words str), length (lines str))
format :: (Int, Int, Int) -> String
format (c,w,l) = unlines $
["Number of characters:"
, show c
, "Number of words:"
, show w
, "Number of lines:"
, show l
]
So (format . cwlcount) :: String -> String and you can write:
main :: IO ()
main = commandLineUtility (format . cwlcount)
Of course there are a million objections to this program, but you can improve it by investigating the parts piecemeal. For one thing, it is irritating that the whole list of characters is brought into memory and three length calculations are made for it separately. The Predude.getLine is not very user friendly either...
At the moment, then, our results look so:
$ ghci Sonia_CS.hs
GHCi, version 7.8.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Main ( Sonia_CS.hs, interpreted )
Ok, modules loaded: Main.
>>> main
Please enter the filename:
Sonia_CS.hs
The file name you have entered is: Sonia_CS.hs
Number of characters:
816
Number of words:
110
Number of lines:
25
Or better:
$ ghc -O2 Sonia_CS.hs
[1 of 1] Compiling Main ( Sonia_CS.hs, Sonia_CS.o )
Linking Sonia_CS ...
$ ./Sonia_CS
Please enter the filename:
/usr/share/dict/words
The file name you have entered is: /usr/share/dict/words
Number of characters:
2493109
Number of words:
235886
Number of lines:
235886
As a junior CS major I'm taking it upon myself to try to cram in learning Haskell over fall breaks (for myself...not sure why I'm torturing myself). I downloaded IntelliJ and installed the official Haskell plugin from Jetbrains.
I'm following instructions from "Learn You a Haskell for Great Good!"
While compiling this code:
test = putStrLn "Hello World!"
I get this error:
Information:Compilation completed with 2 errors and 1 warning in 2 sec
Information:2 errors
Information:1 warning
Error:cabal: build errors.
Warning:ghc: warning: control reaches end of non-void function [-Wreturn-type]
int foo() {}
^
/Users/<USER_NAME>/Documents/Dropbox/Developer/IntelliJ/src/Main.hs
Error:(1, 1) ghc: The function `main' is not defined in module `Main'
I don't have this issue when using a text editor and Terminal...however I love IDE's (sorry VIM guys). Also, I'm running OS X 10.9 which, from my research, has been known to cause issues.
You are missing a main function, just like the error tells you. Just have:
main :: IO ()
main = putStrLn "Hello World!"
or:
test :: IO ()
test = putStrLn "Hello World!"
main :: IO ()
main = test
If it's still giving you problems, then at the very beginning of the file just add:
module Main where
This question already has an answer here:
Why shouldn't I mix tabs and spaces?
(1 answer)
Closed 6 years ago.
I am trying to learn haskell by writing a simple file copy util:
main = do
putStr "Source: "
srcPath <- getLine
putStr "Destination: "
destPath <- getLine
putStrLn ("Copying from " ++ srcPath ++ " to " ++ destPath ++ "...")
contents <- readFile srcPath
writeFile destPath contents
putStrLn "Finished"
This gets me
GHCi, version 6.10.4: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Main ( D:\Test.hs, interpreted )
D:\Test.hs:8:22: Not in scope: `contents'
Failed, modules loaded: none.
Prelude>
I don't understand that compiler error because the variable seems to be ok. What is wrong?
Here is a repro file: at rapidshare
It looks like you mixed tabs and spaces (just look at your question in "edit" view to see the issue). While your editor views the code evenly indented, the Compiler seems to have a different interpretation how wide a tab should be, resulting in the writeFile destPath contents line being additionally indented. So the source is interpreted like this:
...
putStrLn ("Copying from " ++ srcPath ++ " to " ++ destPath ++ "...")
contents <- readFile srcPath writeFile destPath contents
putStrLn "Finished"
In this interpretation of the source code contents is used before it is created, so you get a compiler error.
To avoid these kind of errors best don't use tabs, or at least take additional care that you use them consistently.
That looks correct. I just pasted that into a .hs file and :loaded it into GHCi. Works here and I have the same GHC version as you.