How to get only the object file without main function by ghc? - haskell

[Source Code]
data FooBar = Foo | Bar
[Command]
$ ghc -c foo_bar.hs
foo_bar.hs:1:0: The function 'main' is not defined in module 'Main'
[Configuration]
Glasgow Haskell Compiler, Version 6.12.3, for Haskell 98, stage 2 booted by GHC
version 6.10.4

You should define your type in a module, and then compile it:
module Test where
data FooBar = Foo | Bar
By invoking ghc -c foo_bar.hs, the object file foo_bar.o will be generated without having to define main.

Related

Is it possible to read the derived instances in GHC? [duplicate]

So, in Haskell, it's really easy to do this:
data Foo = Bar | Baz
deriving (Read, Show)
This is great, but I'd like to be able to pass some data as a string from Haskell to the Elm language. The languages are similar enough that, if I had a Haskell implementation of Read, I could easily convert it to Elm by hand.
The problem is, when I use deriving, the function is automatically generated, but I can't actually see what it does.
I'm wondering, is there a way to automatically generate the code for parsing and showing using Read and Show, so that I could actually see the code itself?
You can use the the -ddump-deriv GHC option to see the code for derived instances:
ghc -ddump-deriv test.hs
[1 of 1] Compiling Test ( test.hs, test.o )
==================== Derived instances ====================
Derived instances:
instance GHC.Show.Show Test.FooBar where
GHC.Show.showsPrec _ Test.Foo = GHC.Show.showString "Foo"
GHC.Show.showsPrec _ Test.Bar = GHC.Show.showString "Bar"
GHC.Show.showList = GHC.Show.showList__ (GHC.Show.showsPrec 0)
Generic representation:
Generated datatypes for meta-information:
Representation types:
For stack:
stack build --ghc-options="-ddump-deriv"
Output in my specific case is: .stack-work/dist/x86_64-linux-nix/Cabal-2.4.0.1/build/app/app-tmp/src/

The IO action ‘main’ is not exported by module ‘Main’

I have two haskell files named SimpleJSON.hs and another is Main.hs
--File: SimpleJSON.hs
module SimpleJSON
(
JValue (..)
,getString
,getInt
,getDouble
,getBool
,getObject
,getArray
,isNull
) where
data JValue = JString String
| JNumber Double
| JBool Bool
| JNull
| JObject [(String, JValue)]
| JArray [JValue]
deriving (Eq, Ord, Show)
And
--File: Main.hs
module Main () where
import SimpleJSON
main = print (JObject [("foo", JNumber 1), ("bar", JBool False)])
So while compiling
I am doing
ghc -c SimpleJSON.hs
and
ghc simple Main.hs SimpleJSON.o
Then I am getting error as
Main.hs:1:1: error:
The IO action ‘main’ is not exported by module ‘Main’
|
1 | module Main () where
| ^
How to resolve this compilation error?
Should be
module Main where
or
module Main (main) where
This answer for specifically for reader of Real World Haskell. It seems that the book uses an older version of Haskell where main need not be explicitly mentioned in the list of exports. In the latest version, this is no longer the case.
There are two aspects that need to be mentioned:
you need to write module Main (main) where so that main is exported
you do not need to make an object file of SimpleJSON.hs and mention it while compiling Main.hs i.e simply running ghc -o simple Main.hs will suffice
As a general note, a couple of reviews on the Amazon page for the book mention that some aspects covered in the book are out of date. So, if you are following this book, make it a point to use another source to catch up on the differences.

How to override `doctest` to use my `ghc`?

I have problem using doctest with QuickCheck on NixOS
-- code.hs
--
-- $setup
-- >>> import Test.QuickCheck
--
-- |
-- This test will pass
-- >>> 1 + 1
-- 2
--
-- This test use QuickCheck
-- prob> \xs -> reverse xs = reverse . id $ xs
--
-- The last test will fail to ensure doctest was running
-- >>> 1 == 0
-- True
--
main :: IO ()
main = pure ()
The default haskellPackages.doctest doesn't include QuickCheck
$ nix-shell -p haskellPackages.doctest --run 'doctest code.hs'
code.hs:4: failure in expression `import Test.QuickCheck'
expected:
but got:
<no location info>: error:
Could not find module ‘Test.QuickCheck’
It is not a module in the current program, or in any known package.
Examples: 3 Tried: 1 Errors: 0 Failures: 1
so I try to make an overrride version as mydoctest
# ~/.config/nixpkgs/overlays/doctest.nix
self: super:
with super.haskellPackages;
let
myghc = ghcWithPackages (p: with p;
[
QuickCheck
]);
in
{
mydoctest = doctest.override {
ghc = myghc;
};
}
It still can't find QuickCheck
$ nix-shell -p mydoctest --run 'doctest code.hs'
code.hs:4: failure in expression `import Test.QuickCheck'
expected:
but got:
<no location info>: error:
Could not find module ‘Test.QuickCheck’
It is not a module in the current program, or in any known package.
Examples: 3 Tried: 1 Errors: 0 Failures: 1
but it work if I call it via ghc
$ nix-shell -p mydoctest --run 'ghc -e ":!doctest code.hs"'
code.hs:15: failure in expression `1 == 0'
expected: True
but got: False
Examples: 3 Tried: 3 Errors: 0 Failures: 1
myghc is there but didn't use by mydoctest
$ nix-shell -p mydoctest --run 'doctest --version'
doctest version 0.16.0
using version 8.4.3 of the GHC API
using /nix/store/g1dj8c6h6g8rbb8cv9bgmp1h2f3bxk1l-ghc-8.4.3-with-packages/bin/ghc
$ nix-shell -p mydoctest --run 'which ghc'
/nix/store/qj3vnm903p77nxiraxqxm9b8gbz5rpia-ghc-8.4.3-with-packages/bin/ghc
How can I make doctest to use my override ghc ?
Haskell derivations are not suitable as nix-shell environments by themselves.
The Nixpkgs manual recommends creating a derivation for the purpose of a nix-shell only, using a ghcWithPackages invocation as a dependency.
If the file you're trying to run is part of a haskell package, you can use cabal2nix to do most of the work for you.
I recommend the latter, because it does not pollute your user-wide state (whether profile or user-specific overlay), it is easier to share with others and provides structure that is sufficient to scale from toy example to a valuable package.
I had the same problem trying to get my nix/haskell dev environment set up and found a solution in this reddit post. To get doctest to use a specific version of ghc you can set the environment variable NIX_GHC:
$ doctest --version
doctest version 0.16.3
using version 8.10.3 of the GHC API
using /nix/store/9bm9bs9c4zpl17zdk1d0azid44x3h99b-ghc-8.10.3/bin/ghc-8.10.3
$ export NIX_GHC=/nix/store/zvx9dmfqaa8wibygkbibg4kl98pfj9qv-ghc-8.10.3-with-packages/bin/ghc
$ doctest --version
doctest version 0.16.3
using version 8.10.3 of the GHC API
using /nix/store/zvx9dmfqaa8wibygkbibg4kl98pfj9qv-ghc-8.10.3-with-packages/bin/ghc

Why does ghci not use relative paths?

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

cmdargs value arguments without equals sign

I use cmdargs to write CLI parsers for my Haskell programs.
Let's assume this program, derived directly from their example:
{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs.Implicit
data Sample = Sample {hello :: String} deriving (Show, Data, Typeable)
sample = Sample{hello = def &= help "World argument" &= opt "world"}
&= summary "Sample v1"
main = print =<< cmdArgs sample
If this program is called cmdtest.hs, I can execute
$ runghc cmdtest.hs --hello=world
Sample {hello = "world"}
However, if I leave off the equals sign (like in the -o option in gcc -o foo foobar.c), cmdargs tries to recognize world as a positional argument
$ runghc cmdtest.hs --hello world
Unhandled argument, none expected: world
Is there any option / annotation I can set to allow this syntax in cmdargs?
Update: Using the short option exposes the same problem:
$ runghc cmdtest.hs -h world
Unhandled argument, none expected: world
Update 2: The FlagInfo data in the cmdargs Explicit module seems to suggest it is somehow possible, at least if using Explicit instead of Implicit
Your problem is that you're using opt which makes the value of --hello optional. So --hello world is taken to mean --hello without a value, followed by world as a positional parameter. This is of course a design choice in cmdargs, but I think it's a reasonable one, and it matches the behaviour of most other programs. Take out the opt and see if it works the way you want.

Resources