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.
Related
When I create a .hs file with the following code and load it to ghci using :l, the file loads, but I receive the error <interactive>:1:1: error: Variable not in scope: symbol if I ask for the type of symbol. I am aware that this means that I'm using a name which is not defined in the place in which I'm attempting to use it, but I cannot see what is wrong with the code:
module MyData
(MetricUnit(..),
ImperialUnit(..),
Measurement(..),
convert)
where
data MetricUnit = Meter | Liter | KiloGram
deriving (Show, Eq)
data ImperialUnit = Yard
| Gallon
| Pound
deriving (Show, Eq)
data Measurement = MetricMeasurement Double MetricUnit
| ImperialMeasurement Double ImperialUnit
deriving (Show)
symbol :: MetricUnit -> String
symbol Meter = "m"
symbol Liter = "L"
symbol KiloGram = "kg"
convert (MetricMeasurement x u)
| u==Meter = ImperialMeasurement (1.0936*x) Yard
| u==Liter = ImperialMeasurement (0.2642*x) Gallon
| u==KiloGram = ImperialMeasurement (2.2046*x) Pound
convert (ImperialMeasurement x u)
| u==Yard = MetricMeasurement (0.9144*x) Meter
| u==Gallon = MetricMeasurement (3.7854*x) Liter
| u==Pound = MetricMeasurement (0.4536*x) KiloGram
When typing multi-line things in ghci (like type declarations, class definitions, deriving clauses on another line), you have to enter multi-line mode. You can enter :{ which will put you in a multi-line prompt, then enter your code, then enter :} on another line to exit the multi-line prompt. Then, it'll interpret your code as one chunk instead of many lines.
I guess the issue is that your module starts in this way:
module MyData
(MetricUnit(..),
ImperialUnit(..),
Measurement(..),
convert)
where
hence, the function symbol is not exported by the module.
In GHCi, loading the module as ghci MyData.hs from the command line, or as :load MyData from the GHCi prompt should bypass the export list and give you access to everything.
You could also add symbol to the export list.
You are getting that error because (I guess) you are instead using another way to import your module that won't give you access to non-exported identifiers. Maybe you are importing that module though another one?
I'll start with "can not reproduce":
% cat <<EOF > ap.hs
heredoc> data MetricUnit = Meter | Liter | KiloGram
deriving (Show, Eq)
symbol :: MetricUnit -> String
symbol Meter = "m"
symbol Liter = "L"
symbol KiloGram = "kg"
heredoc> EOF
tommd#ovdak /tmp% ghci ap.hs
GHCi, version 8.6.4: http://www.haskell.org/ghc/ :? for help
Loaded package environment from /Users/tommd/.ghc/x86_64-darwin-8.6.4/environments/default
package flags have changed, resetting and loading new packages...
Loaded GHCi configuration from /Users/tommd/.ghci
[1 of 1] Compiling Main ( ap.hs, interpreted )
Ok, one module loaded.
*Main>
So it loads fine.
Perhaps you are trying to define the code in GHCi instead of load it from a file? In the case see #Aplet123's answer about multi-lines. For an example of a broken use of GHCi, which you might be doing, consider:
*Main> foo :: Bool
<interactive>:1:1: error: Variable not in scope: foo :: Bool
*Main> foo = True
After the first line is entered, GHCi tries to show you foo (print (foo :: Bool)) and not having foo it will tell you foo is not in scope. Again, see the other answer.
The problem was the result of there being another file with the same name.
The problem was resolved when I created a new file with a fresh file name.
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/
I'm writing a module with Haskell and I would like to create two versions of this module :
A 'basic' one (named MyLib) : for speed and public release.
An 'extended' one (named MyLibExt) : for expert and private usage.
For convenience, I would like these two modules (with two differents names) to share the same source files. the two modules will have the same type and same functions with some differences ('extended' version will rely on the 'basic' one).
My idea is to have something like this :
module MyLib where -- for 'basic' version
module MyLibExt where -- for 'extended' version
MyType =
TypeA -- for 'basic' version
| TypeB -- for 'basic' version
| TypeC -- for 'basic' version
| TypeExtendedD -- for 'extended' version
| TypeExtendedE -- for 'extended' version
MyFunction TypeA = ... -- for 'basic' version
MyFunction TypeB = ... -- for 'basic' version
MyFunction TypeExtendedD = ... -- for 'extended' version
and build the two modules with some compilation directive given to GHC/Cabal.
Is it possible to do a such thing with Haskell ?
What are the GHC/Cabal compilation directive which can be useful to make conditionnal building ?
You can't put two modules in the same file. But you can sort of get what you want with a bit of re-exporting.
One file would have both the basic and extended code (I shortened it a bit):
module MyLibExt where
MyType = TypeA | TypeB | TypeC | TypeExtendedD | TypeExtendedE
myFunction TypeA = ...
myFunction TypeB = ...
myFunction TypeExtendedD = ...
then the other file would be the basic one:
module MyLib (MyType (TypeA, TypeB, TypeC), myFunction)
import MyLibExt
This way if someone imports just MyLib they only get access to the basic constructors, but not the extended ones. myFunction will still work on TypeExtendedD values like it would in MyLibExt, but since we're unable to create those values with just MyLib, that's fine.
More generally, when you define your module, you can say what exactly you want to export. Here are some basic examples:
module Example (
exampleFunction, -- simply export this function.
ExampleType1 (), -- export the type, but no constructors.
ExampleType2 (ExampleConstructor1, ExampleConstructor2), -- export the given type and its given constructors. You can't export constructors like functions, you have to do it like this).
ExampleType3 (..), -- export given type and all its constructors.
ExampleClass1, -- export type class, but no functions that belong to it.
ExampleClass2 (exampleFunction2, exampleFunction3), -- export type class and the given functions belonging to it. You can also export these functions as though they were normal functions, like in the first of the examples.
ExampleClass3 (..), -- export type class and all its functions.
module Module1, -- re-export anything that is imported from Module1.
) where
You can export anything that is in scope, including anything that you imported from other modules. In fact if you want to re-export something from other modules, you need to explicitly define an export list like this, by default it will only export whatever is defined in this module.
Consider abstracting. It may not be worth it, but sometimes there is beauty and power hiding, and it can only be teased out with abstraction. For your case MyType and MyFunction, perhaps it goes like this (just an example, and it could look very different depending on your details):
class MyFunction a where
myFunction :: a -> Int
data MyType = TypeA | TypeB | TypeC
instance MyFunction MyType where
myFunction TypeA = 0
myFunction TypeB = 1
myFunction TypeC = 2
data MyTypeExt = Orig MyType | TypeExtendedD | TypeExtendedE
instance MyFunction MyTypeExt where
myFunction (Orig x) = myFunction x
myFunction TypeExtendedD = myFunction TypeC + 1
myFunction TypeExtendedE = myFunction TypeC + 2
That would be the first level. You can go further, making the extension parametric:
data MyTypeExt a = Orig a | TypeExtendedD | TypeExtendedE
instance (MyFunction a) => MyFunction (MyTypeExt a) where
... -- defined so that it works for any myFunction-able Orig
Then it's easy to separate out into different files. But the advantages of abstracting go far beyond splitting things into public and private spaces. If there are two "valid" versions of your code, then those two versions each have consistent meanings. Find what they have in common, see if you can code what they have in common without referencing either one in particular. Then look carefully -- what else has these things in common with your two examples? Can you build your two examples out of yet simpler pieces that also have those things in common? In Haskell, code programs you.
EDIT: Solution: The solution to the problem was to specify the correct vector library in a .cabal file. The tell-tale sign (kindly pointed out by #Daniel below) was that the exact version of the vector was referenced in the error message. Indeed my file was building against vector-0.10.something while vector-fftw was compiled against vector-0.9.1.
I am trying to use the fftw-vector library but am stuck with this type error:
-- test.hs
import qualified Numeric.FFT.Vector.Invertible as FFTI
import qualified Data.Vector.Unboxed as U
z = FFTI.run FFTI.dct1 U.empty
main = putStrLn "Won't compile"
This is the error message:
No instance for (vector-0.9.1:Data.Vector.Generic.Base.Vector
U.Vector Double)
arising from a use of `FFTI.run'
Possible fix:
add an instance declaration for
(vector-0.9.1:Data.Vector.Generic.Base.Vector U.Vector Double)
In the expression: FFTI.run FFTI.dct1 U.empty
In an equation for `z': z = FFTI.run FFTI.dct1 U.empty
but as far as I can tell there is actually an instance of Data.Vector.Gener.Base.Vector for Data.Vector.Unboxed Double (Link) (guess I am wrong).
This is with ghc-7.6.1, vector-0.9.1 and vector-fftw.
(I had to make two tiny changes to vector-fftw so it compiles with base 4.6 and ghc-7.6.1, but that should be unrelated ...)
thank you
EDIT:
two changes I made to vector-fftw:
--- a/Numeric/FFT/Vector/Base.hsc
+++ b/Numeric/FFT/Vector/Base.hsc
## -34,10 +34,11 ## import Control.Monad.Primitive (RealWorld,PrimMonad(..),
import Control.Monad(forM_)
import Foreign (Storable(..), Ptr, unsafePerformIO, FunPtr,
ForeignPtr, withForeignPtr, newForeignPtr)
-import Foreign.C (CInt, CUInt)
+-- import Foreign.C (CInt, CUInt)
import Data.Bits ( (.&.) )
import Data.Complex(Complex(..))
import Foreign.Storable.Complex()
+import Foreign.C.Types
diff --git a/vector-fftw.cabal b/vector-fftw.cabal
index 5ca7c46..0436834 100644
--- a/vector-fftw.cabal
+++ b/vector-fftw.cabal
## -40,7 +40,7 ## Library
Other-modules:
Numeric.FFT.Vector.Base
- Build-depends: base>=4.3 && < 4.6, vector==0.9.*, primitive==0.4.*,
+ Build-depends: base>=4.3 && < 4.7, vector==0.9.*, primitive>=0.4 && < 0.6,
storable-complex==0.2.*
Note that the error message specifies the specific version of the package that defines the class an instance is missing for:
No instance for (vector-0.9.1:Data.Vector.Generic.Base.Vector
U.Vector Double)
That usually means that one of the used packages was compiled against a different version than the one currently used in the project.
I don't see how exactly this would arise, but check for broken packages with ghc-pkg check, and verify that your packages have the correct ids with ghc-pkg describe vector and ghc-pkg describe vector-fftw, possibly vector was rebuilt after building vector-fftw. and the package hashes do not match.
[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.