I'am trying to compile a very small haskell code with ghc:
module Comma where
import System.IO
main = do
contents <- getContents
putStr (comma contents)
comma input =
let allLines = lines input
addcomma [x] = x
addcomma (x:xs) = x ++ "," ++ (addcomma xs)
result = addcomma allLines
in result
The command i'm using to compile is :
ghc --make Comma.hs
And i'm getting this answer:
[1 of 1] Compiling Comma ( Comma.hs, Comma.o )
No file is generated, and there is no warning or errors messages.
If i comment the "module Comma where" line from code it compiles correctly:
[1 of 1] Compiling Main ( Comma.hs, Comma.o )
Linking Comma ...
I don't understand what is happening.
I'm using ghc 7,4,1
(Glasgow Haskell Compiler, Version 7.4.1, stage 2 booted by GHC version 7.4.1)
and ubuntu linux.
I appreciate if anyone could tell why doesn't compile with the module definition
GHC compiles the function Main.main to be the entry point of an executable. When you omit the module declaration, Module Main where is implicitly inserted for you.
But when you explicitly name it something other than Main ghc doesn't find an entry point.
My usual workflow is to use ghci (or ghci + emacs) instead for these snippets which let's you bypass this issue entirely. Alternatively, you could compile with -main-is Comma to explicitly tell ghc to use the Comma module.
No file is generated
Are you sure? I would expect that at least Comma.o and Comma.hi are generated. The former contains the compiled code ready to be linked into an executable, and the latter contains interface information that ghc uses to typecheck modules that import the module Comma.
However, ghc will only link the compiled modules into an executable if there is a main function. By default, that means a function named main in a module named Main. If you don't put an explicit module name, the name Main is assumed, and that's why your test works when you delete the module Comma where line.
To compile and link the Comma.hs file you can either use module Main where instead of module Comma where, or you can use the -main-is flag to tell ghc that Comma.main is to be the main function:
ghc --make -main-is Comma Comma.hs
Or:
ghc --make -main-is Comma.main Comma.hs
If you have a main definition in your file and you want to compile it to an executable you need can only have module Main where.
Related
I have this program Main.hs:
main :: IO ()
main = do
if False then undefined
else do
let x = 5
print x
When I compile it with ghc Main.hs it compils well generating a Main executable, but when (after initializing cabal with cabal init) I try to make a cabal new-run it gives an error:
$ cabal new-run
Build profile: -w ghc-8.6.5 -O1
In order, the following will be built (use -v for more details):
- ghc-vs-cabal-0.1.0.0 (exe:ghc-vs-cabal) (file Main.hs changed)
Preprocessing executable 'ghc-vs-cabal' for ghc-vs-cabal-0.1.0.0..
Building executable 'ghc-vs-cabal' for ghc-vs-cabal-0.1.0.0..
[1 of 1] Compiling Main ( Main.hs, /home/ivan/ghc_vs_cabal/dist-newstyle/build/x86_64-linux/ghc-8.6.5/ghc-vs-cabal-0.1.0.0/x/ghc-vs-cabal/build/ghc-vs-cabal/ghc-vs-cabal-tmp/Main.o )
Main.hs:4:10: error: Empty 'do' block
|
4 | else do
| ^^
With cabal run it also gives error.
I have cabal version 2.4.0.0:
$ cabal --version
cabal-install version 2.4.0.0
compiled using version 2.4.0.1 of the Cabal library
And ghc version 8.6.5:
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.6.5
Does somebody know what is happening?
I know that I can fix it if I add indentation:
main :: IO ()
main = do
if False then undefined
else do
let x = 5
print x
But I want to know why it compiles with ghc but not with cabal new-run
Your code requires a language extension to parse: NondecreasingIndentation. This extension exists to avoid the awkward runaway effect of nested dos
main :: IO ()
main = do
if False then undefined
else do -- next block should be indented in standard Haskell
let x = 5
print x -- ...but this can easily get out of hand if you do it multiple times
NondecreasingIndentation allows a nested do block to register as nested as long as it's indented as much as the containing block, instead of more than the container.
According to the GHC manual, NondecreasingIndentation is on by default but disabled in Haskell2010 mode (unless explicitly enabled again). I can't find the corresponding cabal documentation, but we can probably guess it defaults to specifying Haskell2010.
You can specify extensions in a source file to be enabled or disabled regardless of external options by adding a pragma like
{-# LANGUAGE NondecreasingIndentation #-}
to the very top of the file.
I have a small haskell program which builds and executes with stack ok. When I start it with stack ghci I have an error message which I do not understand and cannot proceed.
GHCi, version 8.10.4: https://www.haskell.org/ghc/ :? for help
[1 of 3] Compiling Lib ( /home/frank/Workspace11/primo/src/Lib.hs, interpreted )
[2 of 3] Compiling YamlRead ( /home/frank/Workspace11/primo/src/YamlRead.hs, interpreted )
[3 of 3] Compiling Main ( /home/frank/Workspace11/primo/app/Main.hs, interpreted )
Ok, three modules loaded.
Loaded GHCi configuration from /home/frank/Workspace11/primo/.ghci
<no location info>: error:
module ‘main:Main’ is defined in multiple files: /home/frank/Workspace11/primo/app/Main.hs
/home/frank/Workspace11/primo/app/Main.hs
I do not see why the same Main is listed twice in the exact same file.
I had a somewhat similar warning message about Paths_primo which is a known bug ( Stack issue #5439 ) and I fixed following the advice see.
What is the cure against this error? I have not used stack much - am I doing something wrong?
This looks like a sign that Main.hs or Main is inadvertently listed multiple times in your Stack package.yaml, in such a way that ghc is invoked with multiple occurrences of it.
This error is possible to reproduce easily with GHC alone, for example:
> echo 'main = putStrLn "hello"' > Hello.hs
> ghc Hello Hello.hs
<no location info>: error:
module ‘main:Main’ is defined in multiple files: Hello.hs Hello.hs
I would run Stack with --verbose and see how GHCi is being invoked, and double-check the package.yaml and generated Cabal file. (If you edit your question to include that, we may be able to offer more specific help with it.)
I can think of several possible reasons for this, such as literally listing Main or Main.hs multiple times (e.g. in exposed-modules, other-modules, main-is); or an interaction like a missing option value in the ghc-options field causing subsequent flags to be misinterpreted.
Main.hs can be listed multiple times in GHCi invocation when it is present in multiple components. Typical way when this happens is:
You create a project with stack new which contains single src/Main.hs file, so package.yaml has an executable entry and no library entry.
Then you add a library and use source-dir: src. Now Main.hs is listed in two components: myapp-lib and myapp-lib-exe. Assuming you package name is myapp.
To solve the problem you should move Main.hs to app dir and update executables:source-dirs to app in package.yaml.
So the problem may happen when Main.hs is listed in multiple components in package.yaml, for example in executables and library.
As I know Text.ParserCombinators.Parsec is replaced by Text.Parsec
Here, it is my environment
4.9.73-1-MANJARO
The Glorious Glasgow Haskell Compilation System, version 8.2.2
cabal-install version 2.0.0.1
compiled using version 2.0.1.0 of the Cabal library
The following source code is my main.hs
module Main where
import System.Environment
import Text.Parsec
main :: IO ()
main = do
args <- getArgs
putStrLn (readExpr (args !! 0))
and then I compile it
$ ghc -package parsec -o main main.hs
It occurs the following error messages
[1 of 1] Compiling Main ( main.hs, main.o )
main.hs:3:1: error:
Could not find module ‘Text.Parsec’
There are files missing in the ‘parsec-3.1.11’ package,
try running 'ghc-pkg check'.
Use -v to see a list of the files searched for.
|
3 | import Text.Parsec
| ^^^^^^^^^^^^^^^^^^
rm: cannot remove '*.hi': No such file or directory
./run.sh: line 11: ./TestProj: No such file or directory
I make sure I have installed parsec. So I want to ask any mistake I've done?
$ cabal install parsec
Resolving dependencies...
All the requested packages are already installed:
parsec-3.1.11
Use --reinstall if you want to reinstall anyway.
Manjaro might have inherited from Arch's issues with Haskell.
What is going on
Arch installs dynamic libraries, but ghc links statically by default. This is also what the error message "There are files missing in the ... package", indicating that the package exists but does not contain what ghc is looking for.
If I try compiling with the -v verbose flag on, the error message expands to:
ghc -v main.hs
(...)
Locations searched:
Text/Parsec.hs
Text/Parsec.lhs
Text/Parsec.hsig
Text/Parsec.lhsig
/usr/lib/ghc-8.2.2/site-local/parsec-3.1.11/Text/Parsec.hi
(...)
In particular, look into the last reported location, which may be different on your system; if my guess is correct, ghc is looking for a static interface file .hi as the message indicates but there is only a dynamic one .dyn_hi.
Fix
Compile with the -dynamic flag.
ghc -dynamic main.hs
And if that works read this to fix the setup:
https://wiki.archlinux.org/index.php/Haskell
You will have to choose between static and dynamic linking; I don't actually understand the trade-off here.
I have a Haskell library with several executables (tests, benchmarks, etc), in total about six. When I do some refactoring in the library, I usually need to make some small change to each of the executables.
In my current workflow, I separately compile each executable (say, with GHCi) and fix each one up. This is tedious because I have to type out the path to each executable, and moreover have to reload all of the (very large) library, which even with GHCi takes some time.
My first thought to solve this issue was to create a single dummy module that imports the executable "Main" modules. However, this (of course) requires that the "Main" modules have a module name like module Executable1 where .... But now cabal complains when compiling the executable that it can't find a module called "Main" (despite explicitly listing "main-is" in the cabal file for each executable.)
I also tried ghci Exec1.hs Exec2.hs ..., but it complains module ‘main#main:Main’ is defined in multiple files.
Is there an easy way to load multiple "Main" modules at once with GHCi so I can typecheck them simultaneously?
Cabal’s main-is option only tells Cabal what filename it should pass to GHC. Cabal does not care about it’s module name.
GHC itself has a flag, also called -main-is, documented here which tells the compiler what module conains the main function.
So this works:
executable foo
main-is: Foo.hs
ghc-options: -main-is Foo
Of course Foo.hs should start with module Foo where… and export main. As usual, the module name and file name needs to match.
This way, all executable can have different module names and you can load them all in GHCi.
If you also want to change the name of the main function, write ghc-options: -main-is Foo.fooMain. I would guess you could even have all executables have the same module but different main-functions this way.
In a Haskell program, what's the best way to use constants defined in C headers?
For this task, hsc2hs is your friend.
For a simple example, let's get the value of INT_MAX from limits.h.
$ cat >IntMax.hsc
module Main where
#include <limits.h>
c_INT_MAX = #const INT_MAX
main = print c_INT_MAX
With hsc2hs, we can #include headers and use the values of constants with the #const directive.
Instead of building by hand, use Cabal:
$ cat >intmax.cabal
Name: intmax
Version: 0.0
Cabal-Version: >=1.2
Build-Type: Simple
Executable intmax
Main-Is: IntMax.hs
Build-Depends: base
Notice that even though the name of the main program is IntMax.hsc, the Main-Is line points to IntMax.hs. When Cabal looks for IntMax.hs but finds IntMax.hsc, it automatically feeds the latter through hsc2hs as part of the build.
$ cabal configure
Resolving dependencies...
Configuring intmax-0.0...
$ cabal build
Prerocessing executables for intmax-0.0...
Building intmax-0.0...
[1 of 1] Compiling Main ( dist\build\intmax\intmax-tmp\IntMax.hs, dist\build\intmax\intmax-tmp\Main.o )
Linking dist\build\intmax\intmax.exe ...
$ ./dist/build/intmax/intmax
2147483647
Note that you'll want to break up lines with multiple constants. Say you're assembling a bitfield to pass to FormatMessage. You'll want to write it as
flags = #const FORMAT_MESSAGE_FROM_SYSTEM
.|.
#const FORMAT_MESSAGE_IGNORE_INSERTS
Putting them all on one line will result in syntax errors.
GHC is moving away from -fvia-c and towards -fasm wherever possible.
One side effect is that your program may be compiled without using any C headers at all, even in -fvia-c mode, in order to ensure that the compilation results are functionally identical to GHC in -fasm mode.
Thus it is necessary to use hsc2hs, c2hs, or other preprocessors run before GHC compiles sources.
c2hs natively supports enum constants... it's been a while, but I think something like this is right.
#c
enum Foo = { Bar, Baz };
void something(enum Foo foo) {}
#endc
{#enum Foo#}
somethingBar = {#call pure something#} (cFromEnum Bar)
#define'd constants are a tick trickier. I've always just copied them inline, or used additional C to transform then into enums or const variables.