I'm building a small haste project where I want to use Elasticsearch. However, bloodhound which seems like the library to go for for elasticsearch in haskell depends indirectly on template-haskell - which isn't supported by haste. Now, I don't need to call elastic from the client, so I don't need bloodhound in haste, but I need to be able to call it from within the same code base as haste is built to use the same code for server and client side. I guess I somehow could have separate client and server side implementations but I really like the haste way.
How can I have calls to dependencies that only exist on the server side in haste?
Preprocessor can be used for this purpose. Haste defines __HASTE__ macro so it should be enough to wrap your code in conditional statement:
{-# LANGUAGE CPP #-}
main = do
#ifdef __HASTE__
print "haste!"
#endif
#ifndef __HASTE__
print "not haste!"
#endif
print "everybody"
Don’t forget to enable C preprocessor extension using {-# LANGUAGE CPP #-} pragma.
You can also achieve similar effect in your ‘.cabal’ file:
Build-Depends:
bytestring >= 0.9.2.1
if flag(haste-inst)
Build-Depends:
base == 4.6.0.1,
array == 0.4.0.1
else
Build-Depends:
base,
array,
random,
websockets >= 0.8
(source https://github.com/valderman/haste-compiler/blob/0.4/libraries/haste-lib/haste-lib.cabal#L63)
Note that the haste-inst flag has been renamed to haste-cabal in the latest development version of Haste.
A potential solution I've thought about is to import a "Shared" module with to different implementations, one client/Shared.hs and one server/Shared.hs and then include one of the implementations using the -i option. So -iclient for haste and -iserver for ghc.
I can't test this at the moment though so I'll have to get back to it.
Related
I am trying to generate documentations for a github library using haddock. Here's the code I entered:
$ find -name '*.hs' | xargs haddock --html -o docs
src/Reflex/Dom/Xhr.hs:154:0:
error: missing binary operator before token "("
#if MIN_VERSION_aeson(1,0,0)
^
Then I looked up the relevant section of my source code Xhr.hs line 154:
import Data.Aeson
#if MIN_VERSION_aeson(1,0,0)
import Data.Aeson.Text
#else
import Data.Aeson.Encode
#endif
I didn't know #if, #else and #endif were part of Haskell but I could guess the meaning. Depending on the version, the code should import either Aeson.Text or Aeson.Encode. Just in case, I looked up the version:
$ ghc-pkg list | grep aeson
aeson-0.11.3.0
This was enough to give haddock difficulty. The info pages get sent to a folder called docs which contains a few empty html files waiting to be populated with the details of the Reflex.Dom library.
That code uses -cpp. Preprocessor directives are not part of the usual Haskell language. In order to correctly parse that code, you need to specify additional options to Haddock:
2.1. Using literate or pre-processed source
Since Haddock uses GHC internally, both plain and literate Haskell sources are accepted without the need for the user to do anything. To use the C pre-processor, however, the user must pass the the -cpp option to GHC using --optghc. [emphasis mine]
There are two problems, though. C preprocessor macro expansion you've posted will only work with GHC 8.0 (or later) if the package is exposed. It should, however, work with cabal haddock or stack haddock regardless of GHC's version. The latter variants are recommended if you try to build the documentation of a cabal/stack package, by the way.
If you still know what you're doing, use haddock --optghc=-cpp.
I have decided to use my own Prelude for a larger project (containing some libraries and some executables). The Prelude doesn't export some partial functions and exports some common functions (i.e. from Control.Monad etc.). However, I am fighting with the way how to do it. I have tried:
use base-noprelude. Create Prelude.hs in module my-common-module.
Same as above, but in the my-common-module create My.Prelude instead. In every other module create a directory 'prelude', put it into hs-source-dirs cabal section, create a file prelude/Prelude.hs with import My.Prelude
The problem is that in 1) I cannot just run ghci, as I get conflicting base and my-common-module. In 2) ghci works, cabal repl somehow doesn't as it fails mysteriously with 'attempting to use module ‘Prelude’ (prelude/Prelude.hs) which is not loaded'. Additionally, base-noprelude doesn't seem to like ghcjs, which I want to use for part of the project (code sharing).
It seems to me the only way currently is to start each and every file with:
import Prelude ()
import My.Prelude
or
{-# LANGUAGE NoImplicitPrelude #-} -- or extensions: NoImplicitPrelude in .cabal
...
import My.Prelude
The 'extensions: NoImplicitPrelude' option seems to me best as it requires every file to import My.Prelude otherwise it won't work. Am I missing some obvious way that would achieve custom Prelude and at the same time work with cabal repl and ghcjs?
Update: base-noprelude works with GHCJS when I manually remove the reexport of GHC.Event.
Update: Ok, I spent some time with this and I should have spent more. It seems to me that 1) is the right way to go. cabal repl works (thanks Yuras), ghci must be loaded with ghci -hide-package base and works too.
I ended up with this setup that seems to work:
Create a special package my-prelude. This package exports the Prelude, can contain other modules, it can depend on base. You may need to use {-# LANGUAGE NoImplicitPrelude #-} in some modules to avoid circular dependencies. E.g. you may want to have some orphan instances defined and exported by your custom Prelude in separate files (e.g. Orphans.Lib_aeson), these files need the NoImplicitPrelude.
In your main project, libraries etc. change the dependencies in cabal from base to base-noprelude, my-prelude.
What works:
cabal repl
ghci/runghc works, but you have to start it with ghci -hide-package base; otherwise there will be conflict between base and my-prelude
What does not work:
cabal repl in the my-prelude package.
I've got the following situation:
Library X is a wrapper over some code in C.
Library A depends on library X.
Library B uses Template Haskell and depends on library A.
GHC bug #9010 makes it impossible to install library B using GHC 7.6. When TH is processed, GHCi fires up and tries to load library X, which fails with a message like
Loading package charsetdetect-ae-1.0 ... linking ... ghc:
~/.cabal/lib/x86_64-linux-ghc-7.6.3/charsetdetect-ae-1.0/
libHScharsetdetect-ae-1.0.a: unknown symbol `_ZTV15nsCharSetProber'
(the actual name of the “unknown symbol” differs from machine to machine).
Are there any workarounds for this problem (apart from “don't use Template Haskell”, of course)? Maybe library X has to be compiled differently, or there's some way to stop it from loading (as it shouldn't be called during code generation anyway)?
This is really one of the main reasons that 7.8 switched to dynamic GHCi by default. Rather than try to support every feature of every object file format, it builds dynamic libraries and lets the system dynamic loader handle them.
Try building with the g++ option -fno-weak. From the g++ man page:
-fno-weak
Do not use weak symbol support, even if it is provided by the linker. By default, G++ will use weak symbols if they are available. This option exists only for testing, and should not be used by end-users; it will result in inferior code and has no benefits. This option may be removed in a future release of G++.
There is another issue with __dso_handle. I found that you can at least get the library to load and apparently work by linking in a file which defines that symbol. I don't know whether this hack will cause anything to go wrong.
So in X.cabal add
if impl(ghc < 7.8)
cc-option: -fno-weak
c-sources: cbits/dso_handle.c
where cbits/dso_handle.c contains
void *__dso_handle;
I have a simple web app written with scotty.
I would like to use fay to generate the front-end JS code and use shared types between the frontend and the backend.
At the moment, I run my app using cabal run: in my .cabal file I defined an "executable" and "build-depends" depends on base.
When I include "fay" and "fay-base" in "build-depends", compilation fails because Prelude is ambigous.
I understand that "fay-base" is supposed to replace the standard prelude, but I still do want to use the standard prelude in the backend code.
So, how should I write my .cabal file and what language extensions should I use in my .hs files so that std Prelude and fay Prelude can coexist? Is this the right approach?
I am using fay-0.20.1.1.
You can have fay as a dependency, it's a normal Haskell package and doesn't cause any clashes.
fay-base doesn't replace base. It's Fay's version of base and can only be used with Fay code, and vice versa.
If you want to make sure fay-base is pulled in as a dependency you can depend on another fay package (such as the small fay-text to get fay-base included as a transitive dependency)
You have some options on when to build your fay code:
At program startup using Fay's API, or fay-builder which lets you specify fay options in your Cabal file (see this blog post but skip the part about custom cabal hooks!)
On every HTTP request, useful for development. You can use the Fay API, fay-builder, yesod-fay, snaplet-fay, or happstack-fay for this.
As a Cabal hook with a custom Setup.hs (Again, bad idea)
I see this used often to make modules compatible with GHC and Hugs, but google is not helping me learn more about it.
What can I put inside the conditional? Can I make parts of a module conditional on what version of 'base' is in use?
EDIT 3/2017: This is a great resource: https://guide.aelve.com/haskell/cpp-vww0qd72
The GHC documentation has a section relating to the C pre-processor that documents some of the predefined
pre-processor macros.
The Cabal documentation has a section relating to conditional compilation that gives an example relating to base. If you are writing a portable package, you should be using Cabal, anyway.
In addition to the very useful flags defined by GHC (OS, architecture, etc), when using cabal other flags and macros are defined.
Check Package Versions
Here's a use from crypto-api that checks the version of the tagged package being used:
#if MIN_VERSION_tagged(0,2,0)
import Data.Proxy
#endif
Custom CPP Defines Based on Cabal Flags
You can define CPP symbols dependent on cabal flags. Here's an (unnecessarily complex) example from pureMD5 (from the .cabal file):
if arch(i386) || arch(x86_64)
cpp-options: -DFastWordExtract
Inside the .hs module you can then use #ifdef, for example:
#ifdef FastWordExtract
getNthWord n b = inlinePerformIO (unsafeUseAsCString b (flip peekElemOff n . castPtr))
#else
... other code ...
#endif
For more information you can see the Cabal users guide. This page has the "conditional compilation" information you're probably looking for.
#ifdef and friends are used by the C preprocessor (CPP). They provide a way to compile code conditionally. You can enable the use of the CPP by adding the pragma {-# LANGUAGE CPP #-} on top of a file.
Many programs that deal with Haskell code set some macros for the preprocessor (eg. GHC sets __GLASGOW_HASKELL__ to the version of GHC), so one can conditionally compile code, for instance to use different properitary libraries for Hugs and GHC.
If you run your Haskell compiler with the -cpp option, it will first preprocess the source files with the CPP (C Pre Processor).
Take a look at the section 4.11.3. Options affecting the C pre-processor here.