Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to correctly define your 'company' Prelude

Tags:

haskell

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:

  1. use base-noprelude. Create Prelude.hs in module my-common-module.

  2. 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.

like image 633
ondra Avatar asked Oct 19 '22 15:10

ondra


1 Answers

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.
like image 125
ondra Avatar answered Nov 15 '22 08:11

ondra