I have two .hs files: one contains a new type declaration, and the other uses it.
first.hs:
module first () where
type S = SetType
data SetType = S[Integer]
second.hs:
module second () where
import first
When I run second.hs, both modules first, second are loaded just fine.
But, when I write :type S on Haskell platform, the following error appears
Not in scope : data constructor 'S'
Note: There are some functions in each module for sure, I'm just skipping it for brevity
module first () where
Assuming in reality the module name starts with an upper case letter, as it must, the empty export list - () - says the module doesn't export anything, so the things defined in First aren't in scope in Second.
Completely omit the export list to export all top-level bindings, or list the exported entities in the export list
module First (S, SetType(..)) where
(the (..) exports also the constructors of SetType, without that, only the type would be exported).
And use as
module Second where
import First
foo :: SetType
foo = S [1 .. 10]
or, to limit the imports to specific types and constructors:
module Second where
import First (S, SetType(..))
You can also indent the top level,
module Second where
import First
foo :: SetType
foo = S [1 .. 10]
but that is ugly, and one can get errors due to miscounting the indentation easily.
Module names start with a capital - Haskell is case sensitive
Line up your code at the left margin - layout is important in Haskell.
The bit in brackets is the export list - miss it out if you want to export all the functions, or put everything you want to export in it.
First.hs:
module First where
type S = SetType
data SetType = S[Integer]
Second.hs:
module Second where
import First
Related
I am a newbie to function programming. How can I pass a value from one Haskell program to another? Suppose we have
in a file called Addition.hs:
Addition::Int
Addition = value+10
in a file called Value.hs:
value::Int
value=20
With PHP, for example, if include a file in another, I can access its classes. Is it possible in Haskell? That would make my program clearer.
You can reference members of other modules if you import that module, and the module exports the member:
Value.hs
module Value ( value ) where
value :: Int
value = 20
Addition.hs
module Addition ( addition ) where
import Value
addition :: Int
addition = value + 10
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.
Is it possible to check if a function is defined, and use it as the Just value of a Maybe type if it is? And use Nothing if it's not defined, of course.
I'm writing a wrapper around atom for use with the TI MSP430 line. Part of what I'm doing is making a function that quickly compiles the code in the right format for MSP430 controllers - for example, compiling an atom to use in a timer interrupt requires a function definition like so:
#pragma vector=TIMERA0_VECTOR __interrupt
void timerAisr(void) {
...
}
At the moment, I have an object that holds references to the function the user would like to use for each different ISR. It looks a bit like this:
mspProgram = MSP430Compilation {
setupFn = Nothing,
setupFnName = "setup",
loopFn = Nothing,
loopFnName = "loop",
timerAISR = Nothing,
timerAISRName = "timerAISR",
And so on. Very configurable - you can choose the name of the function to output in C code, and the Atom to compile for that function. But I've decided I'd like to take more of a convention-over-configuration approach and basically assume some sensible function names. So instead of passing one of these configuration objects, I want the compilation code to check for definitions of sensibly-named functions.
For example, if the user defines an Atom called timerAISR, then my code should compile that atom to a C function named the same, with the appropriate #pragma matter for it to service the timer A interrupt.
So what I need to do is sort of meta-Haskell, checking if the user has defined a function and using that in my library code. I imagine this might involve template Haskell, so I'm off to research it.
EDIT:
I've realised that my original solution was too simplistic once I tried to fit it into my actual code. I hadn't absorbed Haskell's namespacing, so I didn't realise that lookupValueName would not work on values defined in user code. Here's the situation I'm dealing with:
main.hs:
module Main where
import Library
a = 1
main = libraryMain
Library.hs:
{-# LANGUAGE TemplateHaskell #-}
module Library where
import Template
libraryMain :: IO ()
libraryMain = do
$(printSomethingIfIsDefined "a")
$(printSomethingIfIsDefined "b")
Template.hs:
{-# LANGUAGE TemplateHaskell #-}
module Template where
import Language.Haskell.TH
printSomethingIfIsDefined name = do
maybeFn <- lookupValueName name
case maybeFn of
Just fn -> [| putStrLn "It's defined!" |]
Nothing -> [| return () |]
This prints nothing. If I define a in Library.hs, it will print out once, because a is defined in that scope.
I am trying to implement a ray data type using the Vector type found here: http://www.haskell.org/haskellwiki/Numeric_Haskell:_A_Vector_Tutorial#Importing_the_library
The Vector will only hold doubles, so I would like to use the Unboxed version of the Vector type.
Here is the code I am trying to compile:
module Main where
import qualified Data.Vector.Unboxed as Vector
data Ray = Ray Data.Vector.Unboxed Data.Vector.Unboxed
The error I get is
Not in scope: type constructor or class `Data.Vector.Unboxed'
Failed, modules loaded: none.
The module Data.Vector.Unboxed exports a type constructor Vector which takes as an argument the type you want to store. Since you renamed this module to Vector as well, the qualified name for this type is Vector.Vector. Assuming you want two vectors of doubles, you should therefore use it like this:
data Ray = Ray (Vector.Vector Double) (Vector.Vector Double)
Normally, when you import something, you do it like this:
import Data.Foo -- A module that contains "data Bar = Bar ..."
myfunction = Bar 3 2 4 -- Use Bar
As you can see, you can access all of the stuff in the Data.Foo module directly, as if you were writing code in that same module.
You can instead import something with qualification, which means that you must specify the full module "path" to the thing that you are referring to every time you access it:
import qualified Data.Foo -- A module that contains "data Bar = Bar ..."
myfunction = Data.Foo.Bar 3 2 4 -- Use Bar
Here, you must specify the full "path" to the data type that you're accessing, because the module has been imported as qualified.
There is another way to import something with qualification; you can specify an alias for the module "path" like so:
import qualified Data.Foo as Foo -- A module that contains "data Bar = Bar ..."
myfunction = Foo.Bar 3 2 4 -- Use Bar
We have renamed the Data.Foo part to simply Foo. This way, we can write Foo.Bar when referring to the data constructor.
You imported the module Data.Vector.Unboxed with the alias Vector. This means that when you want to access the Vector data type, you must use Vector.Vector. I'd recommend that you import vectors like this instead:
import Data.Vector.Unboxed (Vector)
import qualified Data.Vector.Unboxed as Vector
This way, you import the Vector type directly, so that you can access it without any module qualifiers, but when you want to use Vector functions, you need to add the Vector prefix (For example Vector.null ...).
suppose you have two modules like
module Foo.A where
foo = 42
and
module Foo.B where
foo = 12
and you want to write a super module
module Foo (
module Foo.A
, module Foo.B
) where
import Foo.A
import Foo.B
which re-exports those modules, you would get a name clash.
Is there a solution for this?
Basically, no. This has been a long-standing feature request by people like the authors of Gtk2hs. Gtk2hs has a very broad module hierarchy where it might make sense to both:
Use the same name in several different modules (e.g. newButton in both Graphics.UI.Gtk.Buttons.Button and Graphics.UI.Gtk.Buttons.CheckButton)
Provide the convenience to the user of importing all these modules with a single import statement
For now, if you want to reexport several modules together all you can do is:
Avoid reusing names in the modules you wish to reexport
Where appropriate, use type classes to allow the same name to be used for several different purposes
Good question. The Haskell Report addresses this:
Exports lists are cumulative: the set of entities exported by an export list is the union of the entities exported by the individual items of the list.
[...]
The unqualified names of the entities exported by a module must all be distinct (within their respective namespace).
According to my limited Haskell knowledge I'd say it's not possible.
You can't export both foos without the name clash unless you use a typeclass (which I shall elaborate on), but there are other options.
You could opt to hide one of the versions of foo:
module Foo
(
module Foo.A,
module Foo.B
)
where
import Foo.A
import Foo.B hiding (foo)
This isn't ideal if you genuinely need both, but if one is rarerly used then it may be simpler to just hide it and expect people to manually reinclude (e.g. by import qualified Foo.B as B (foo), providing B.foo) it if they need it.
You could opt to hide both versions of foo and document that you expect the end user to manually import them if they need them. Under such a scheme, the user could do something like the following:
import Foo.A as A (foo)
import Foo.B as B (foo)
main :: IO ()
main = do
print A.foo
print B.foo
This is actually a fairly common thing to have to do when dealing with multiple container types since many different container types export functions like empty, null and singleton. (To the point where I wish there were actually typeclasses for those, since they are such common operations.)
If you really need both and you're prepared to do a bit of export gymnasics, you can reexport both under different names from within Foo itself:
module Foo (module Foo) where
-- Note that in this case it is important
-- that the module alias matches the
-- name of the exporting module ('Foo')
import Foo.A as Foo hiding (foo)
import Foo.B as Foo hiding (foo)
import qualified Foo.A
import qualified Foo.B
fooA = Foo.A.foo
fooB = Foo.B.foo
Thus any module importing Foo will get Foo.A.foo as fooA (with a value of 42) and Foo.B.foo as fooB (with a value of 12).
If you only have a few clashes to resolve then this is probably the most balanced solution
As another answer has already mentioned, you can use a typeclass, though depending on the context this may be a misuse of the typeclass system.
You could achieve that like so:
module Foo.C where
-- The 'a' dummy argument is necessary to disambiguate
-- which version of 'foo' you intend to use.
class FooProvider a where
foo :: a -> Int
module Foo.B where
import Foo.C
data FooB = FooB
instance FooProvider FooB where
foo _ = 12
module Foo.A where
import Foo.C
data FooA = FooA
instance FooProvider FooA where
foo _ = 42
module Foo (module Exports) where
-- In this case the name of the
-- module alias is unimportant
-- as long as all modules use the same alias.
import Foo.A as Exports
import Foo.B as Exports
import Foo.C as Exports
import Foo
-- 'FooA' and 'FooB' exist solely for
-- the purpose of disambiguating the
-- different versions of 'foo'.
main :: IO ()
main = do
print (foo FooA)
print (foo FooB)
Generally this is less desirable than the aforementioned solutions, particularly for something as simple as a named constant, but sometimes it makes sense to introduce a typeclass. For example, a typeclass such as this:
class Container c where
empty :: c a
singleton :: a -> c a
null :: c a -> Bool
Would work for a number of container types, including [] ('List'), Set, Maybe. Without singleton, it would apply to even more types (e.g. Map, Seq, IntMap). (Note that this could also have included some kind of length function since an empty container would have a length of 0 and a singleton container would have a length of 1. It would however clash with the length in Prelude, which is based on Foldable.)
There may be other possibilities that make use of typeclasses and possibly compiler extensions, but I suspect they'll only increase in complexity from herein.