export haskell module with different hierarchy - haskell

In Haskell, modules name and file name containing the module have to be the same.
The problem is is not only the file name but the includes the all path, so you have (AFAIK) to create a directory structure matching the module hierarchy, which is a bit annoying.
For example, let's say that I'm writing a datatype D in a module M which I think should be in Database.
The module name should be Database.M.T. As my main directory is already called M (the name of the package) I end up with the following directory structure :
M:
|
+-- Database:
|
+-- M:
|
+ A.hs
Is that possible to just do :
M:
|
+ A.hs
And export M as Database.M ?

This isn't possible at present, short of using symlinks or similar to point Database.M to M which would have various problems with portability and version control.
Simon Marlow proposed a new option for GHC to add support for aliases a few months ago: http://www.haskell.org/pipermail/glasgow-haskell-users/2014-April/024920.html
His idea was that you could run ghc with a new variant of the -i option:
ghc -iDatabase.M=M
and then anything in the M folder would be treated as being part of Database.M as you want.
You'd also be able to put the new option in the hs-source-dirs field in .cabal files.
However there were various objections to the proposal so he's withdrawn it for now. The main problems were that it adds complexity and several other tools (e.g. cabal) would also have to be changed to support it.

Related

Haskell: Default module prefix [duplicate]

In Haskell, modules name and file name containing the module have to be the same.
The problem is is not only the file name but the includes the all path, so you have (AFAIK) to create a directory structure matching the module hierarchy, which is a bit annoying.
For example, let's say that I'm writing a datatype D in a module M which I think should be in Database.
The module name should be Database.M.T. As my main directory is already called M (the name of the package) I end up with the following directory structure :
M:
|
+-- Database:
|
+-- M:
|
+ A.hs
Is that possible to just do :
M:
|
+ A.hs
And export M as Database.M ?
This isn't possible at present, short of using symlinks or similar to point Database.M to M which would have various problems with portability and version control.
Simon Marlow proposed a new option for GHC to add support for aliases a few months ago: http://www.haskell.org/pipermail/glasgow-haskell-users/2014-April/024920.html
His idea was that you could run ghc with a new variant of the -i option:
ghc -iDatabase.M=M
and then anything in the M folder would be treated as being part of Database.M as you want.
You'd also be able to put the new option in the hs-source-dirs field in .cabal files.
However there were various objections to the proposal so he's withdrawn it for now. The main problems were that it adds complexity and several other tools (e.g. cabal) would also have to be changed to support it.

Haddock link to functions in non-imported modules

In module B I have documentation with a link 'A.foo', linking to the foo member of module A. In module A I import module B. Haddock renders this as a link to A.html#t:foo, namely pointing at the type foo (which does not exist) not the function foo, which is at A.html#v:foo.
Why does Haddock link to t: for variables that start with a lower case letter? Is that a bug? For 'A.Foo' I can see that it could be a type or a constructor, so there are namespacing issues. For foo it seems a variable is at least most plausible.
Is there any way to fake a link? I am writing this in code samples, so I need it to be rendered as foo. I tried anchors, but they render as the module name, and for direct hyperlinks you have no control over the displayed text.
I considered a post processor (replacing t:[a-z] with v:), but that requires a custom Setup.hs which causes problems and is quite ugly.
I couldn't find any Haddock command line flags to obtain a more reasonable behavior, such as specifying that foo is a variable.
I can't add an import of A to B without introducing circular imports, which is vile to add purely for documentation.
I am running into this problem in the Shake documentation, where as an example removeFilesAfter does not get the right link.
I can partially answer the the first question (Why?); not sure if it is a bug or desired behaviour.
When haddock resolves references in LexParseRn.rename, it tries to look up the identifier in the environment (via lookupGRE_RdrName). This ought to fail. Next it looks as what the thing could mean (using dataTcOccs from GHC’s RnEnv). The relevant lines are:
dataTcOccs :: RdrName -> [RdrName]
-- Return both the given name and the same name promoted to the TcClsName
-- namespace. This is useful when we aren't sure which we are looking at.
dataTcOccs rdr_name
[...]
| isDataOcc occ || isVarOcc occ
= [rdr_name, rdr_name_tc]
[...]
where
occ = rdrNameOcc rdr_name
rdr_name_tc = setRdrNameSpace rdr_name tcName
so it returns the name first interpreted as whatever it was before (likely a link to a value), and then interpreted as a type constructor. How can a regular name be a type constructor? My guess is that this was added when TypeOperators were reformed in GHC 7.6, which now do share the namespace with value-level operators.
Then haddock matches on the result: If the first one is a type constructor, use that, otherwise use the second. So either it was a type constructor before, then this is used. Or it was not, but then the modified version generated by dataTcOccs is to be used.
It seems to me that haddock should just always use the first option here, and the code is just a mislead copy from how multiple results are used when they can actually be resolved.
This was a Haddock bug #228 and Neil's Haddock bug #253 and the fix has been upstream for few months. You can build GHC HEAD and rebuild your documentation or wait for 7.8 and do it then.

Haskell skeleton template project for beginners

I have 3 data constructors say A,B and C that are defined in files A.hs, B.hs, C.hs and the files are in the directory project-utils.
Now I want to use these data constructors in parts of other projects. These projects reside in totally different directories.
How do I import the data and type constructors of A, B and C in such project files?
Thanks to the first answer given below, I realized that I am looking for a skeleton to organize such project in a better way. I searched but could not find any such project skeleton.
The link provided there contains many things that are described in vague manner. For example, on line 5 there it is simple written as "..."
What i am looking for is,
The skeleton project should not be very simple "single" file project as is given on the Haskell site. But should NOT be overly complex with tons of dependencies etc that we see in many projects on hackage.
Edit: I changed the title to reflect my problem in a better way. Sorry for the inconvenience.
Make a cabal pkg out of them and install that package locally.
Follow a directory stucture as here and use those constuctors in a project rather than across projects. The stucture mentioned is basically a structure of a cabal package.
Manually add the input source while compiling through ghc or loading in ghci.
Example
ghci -i project-utils/A.hs Foo.hs
where Foo.hs uses elements exported by A.hs
May not be exactly what you're looking for, but for future readers of this question, a Haskell skeleton/template project was just released here:
https://github.com/tfausak/haskeleton
It does add some dependencies like hlint and hspec. Here is the blog post, which goes through each of the individual decisions:
http://taylor.fausak.me/2014/03/04/haskeleton-a-haskell-project-skeleton/
I found this: how to write a haskell program link as a handy reference.
#Tem Pora : you need to install yesod and yesod-bin. This link talks more about the scaffolding
cabal install yesod
cabal install yesod-bin
<cdtoprojdir> yesod init
Hope this helps.

What's the canonical way to share modules between projects?

Suppose there are three projects A, B and C. The modules in C will be shared by A and B. Because there is no java's CLASSPATH thing, then do we need to use absolute path when importing modules from C ?
Any suggestion is appreciated !
I urge you to cabalise your projects.
But if for some reason you don't want to do this, then the nearest thing to the java classpath is the -i switch to ghc. Note that the current directory needs to appear explicitly in the list.
The canonical way is to choose carefully where they should sit in the module hierarchy and make each project into a fully featured Cabal package, then install them locally so that they're a part of the namespace for your compiler locally.
This way the modules of each are available to any source code you're writing.
If (for example) you use the leksah IDE it'll do a lot of the work for you.
If by "projects" you mean Cabal packages, the standard thing to do would be to export whatever modules are necessary from C and then have A and B depend on the C and import them. It's not a good idea to have source files in a package directly depend on files that are aren't part of that package.

make one static library from whole project with cmake

c++-project, say, foo is maintained by the cmake.
One wants to create one library libfoo.a (with all classes/methods/functions created at the whole source-tree) to make possible creating programs that could linked to the library with -lfoo.
ok, let's consider now a toy example, and the prolbem will be clear. Directory foo (root of the project) contains directories a, and b. Two CmakeLists.txt are created:
# a/CMakeLists.txt
add_library(A <a_sources>)
# b/CMakeLists.txt
add_library(B <b_sources>)
And one CMakeLists.txt for root directory:
add_subdirectory(a)
add_subdirectory(b)
add_library(foo <foo_sources>
target_link_libraries(foo A B)
That was a surprise for me: after building libfoo.a contains only methods from foo_sources, and a_sources,b_sources are excluded.
That is ok in the case when executables are built with the same project: while creating executables cmake "guesses" that a and b must be linked if it is linked to foo.
But in the case executable is created "outside" project to use library foo one must link with -lfoo -la -lb, now imagine a project with lots of subdirectories - how to deal with it? so question is "how to create one library, aggregating methods from whole project with means of cmake?"
Googling led me to relatively recently embedded (appeared in 2.8.8) OBJECT library opportunity. Nice example of using it is shown here. Now the problem above can be solved with that:
# a/CMakeLists.txt
add_library(A OBJECT <a_sources>)
# b/CMakeLists.txt
add_library(B OBJECT <b_sources>)
# foo/CMakeLists.txt
add_subdirectory(a)
add_subdirectory(b)
add_library(foo <foo_sources> $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>)
problem seems to be solved, unfortunately, not quite.
if dependency chain is longer than 2, for example, foo depends on A, which depends on B, problem still remains.
That is because,
Object libraries may contain only sources (and headers) that compile to object files.
and
Object libraries cannot be imported, exported, installed, or linked.
(quotes are taken from the same link)
I've tried several combinations of target_link_library(), add_library(), add_library(... OBJECT ..) trying to link A and B to foo without success (error during cmake-process.)
I must be loosing something simple, please help, thank you!
I am not sure is it important: project is maintained at the linux.
I think you're getting tangled up in the term "depends on". If you're building a library named foo and it has two parts, A and B, it doesn't matter whether A depends on B; the library should contain both. The CMake code you've shown will build foo properly.
Yep, I support answer #Pete Becker# . But it should be said as well that those libraries a $<TARGET_OBJECTS:A> and $<TARGET_OBJECTS:B> actually not a libraries at all, but rather cmake internal list of object modules. There is no dependencies between compilation of object modules (except auto-generated sources) so they can be done in any order and in parallel.
I guess more correct term for your intention is gathering together several TARGET_OBJECTS under single object library. That's really bad that you can't write add_library(B OBJECT b.cpp $<TARGET_OBJECTS:A>). But you always can implement this by yourself:
add_library(A OBJECT a.cpp)
set(A_OBJECTS $<TARGET_OBJECTS:A>)
add_library(B OBJECT b.cpp)
set(B_OBJECTS $<TARGET_OBJECTS:B> ${A_OBJECTS})
add_library(foo ${B_OBJECTS})
I.e just create special variables _OBJECTS to use them whenever you want to include those object libraries in library, executable or as part of other object library with that _OBJECTS flavor.

Resources