Setting import path in an OPTIONS pragma - haskell

According to the GHC 8.4.3 flag reference, the -i flag is dynamic, which means it should be settable by an OPTIONS pragma.
So I tried the following:
.
├── Main.hs
└── imp
└── Imported.hs
Contents of imp/Imported.hs:
module Imported (foo) where
foo :: String
foo = "Foo"
Contents of Main.hs:
{-# OPTIONS_GHC -iimp #-}
import Imported (foo)
main :: IO ()
main = putStrLn foo
However, if I try to run Main.hs using runhaskell, it complains that Imported cannot be found:
$ runhaskell -v Main.hs
...
Main.hs:2:1: error:
Could not find module ‘Imported’
Locations searched:
Imported.hs
Imported.lhs
Imported.hsig
Imported.lhsig
How do I specify the -i flag in an OPTIONS pragma?

This appears to be a regression of a documentation bug that was fixed in 2007 and then re-broken in 2014 when a bunch of "static"s were changed to "dynamic"s in the flag reference table. As per the linked bug report, the -i flag is not fully dynamic. It can be :set in GHCi but can't be specified in an OPTIONS_GHC line.

Related

Why is stack not auto detecting my module?

I am trying to write a script that uses Diagrams but the stack package detection feature is confusing me. I have two files and when the support module imports SVGFonts stack doesn't add it to the list of modules that are found. Instead, it's hidden. When the import is in the main file, however, it downloads it and finds it for the build just fine.
Main.hs
-- stack --resolver lts-19.0 script
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
import Diagrams.Prelude
import MyMod (val)
import Diagrams.Backend.SVG
main = print val
MyMod.hs
module MyMod where
import Diagrams.Backend.SVG
val = 1
And I am getting this error
Could not load module ‘Diagrams.Backend.SVG’
It is a member of the hidden package ‘diagrams-svg-1.4.3.1’.
You can run ‘:set -package diagrams-svg’ to expose it.
(Note: this unloads all the modules in the current scope.)
Use -v (or `:set -v` in ghci) to see a list of the files searched for.
|
3 | import Diagrams.Backend.SVG (loadFont)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
How can I get stack to automatically find that I need SVGFonts and import it properly without adding the import to my main file?

Haskell -- suppress import errors

I have a bunch of Haskell files I need to compile with GHC, but some import libraries that don't exist. Is there a way to suppress the compiler error: Could not find module, and only make it throw during runtime? Something like -fdefer-type-errors does, but for imports.
Editing the files is not an option at the moment, and most imports are not even used by the program, so would never throw if it compiled.
You can use cabal's mixins to expose other, existing, modules with the names of the modules you desire to exist. For example you might have a file:
module MyLib (someFunc) where
import Module1
import Module2
someFunc :: IO ()
someFunc = putStrLn "someFunc"
So Module1 and Module2 do not actually exist. But you can point those modules to anything, such as Data.Map and Data.Set using the cabal file:
library
exposed-modules: MyLib
-- Modules included in this library but not exported.
-- other-modules:
-- LANGUAGE extensions used by modules in this package.
-- other-extensions:
build-depends: base ^>=4.14.0.0, containers
hs-source-dirs: src
default-language: Haskell2010
mixins:
containers (Data.Map as Module1, Data.Set as Module2)
There is no option in GHC that allows compilation when an imported module can not be found.

How to load everything from Haskell module in GHCi

I would like to import hidden data constructor from a module being in GHCi. It looks like it is not possible for packages.
For source files :l is working
stack ghc --package ghc
:set -XStandaloneDeriving
import Module
-- ModuleName is not exposed
deriving instance Show ModuleName -- fails
Update 1. I found an article to call hidden functions but it is not exactly I was looking. Probably TH can do more.

Haskell package vector-space fails at compile time

I tried to install the Haskell diagrams library and one of the dependencies cannot be installed. Being not that experienced to haskell, I cannot quite see how to resolve this error.
I removed warnings that I believe are not related to the failed build (------ warnings ommitted (-Winvalid-pp-token) -----)
[hsenv]➜ ~HSENV cabal install vector-space-0.8.5
Resolving dependencies...
Downloading vector-space-0.8.5...
Configuring vector-space-0.8.5...
/var/folders/nq/fx4vf3v14jz9b8mldvcyv1xr0000gn/T/23218.c:1:12:
warning: control reaches end of non-void function [-Wreturn-type]
int foo() {}
^
1 warning generated.
Building vector-space-0.8.5...
Preprocessing library vector-space-0.8.5...
------ warnings ommitted (-Winvalid-pp-token) -----
src/Data/VectorSpace.hs:4:3:
error: invalid preprocessing directive
#-}
^
------ warnings ommitted (-Winvalid-pp-token) -----
2 warnings and 1 error generated.
Failed to install vector-space-0.8.5
cabal: Error: some packages failed to install:
vector-space-0.8.5 failed during the building phase. The exception was:
ExitFailure 1
I presume you’re on OS X with Xcode 5 installed? There are instructions for that.
Xcode 5 supplies Clang as the C compiler, and with respect to pre-processing there are some “differences of interpretation” between it and GCC. These differences can affect some Haskell code that uses the CPP extension. An alternate approach for users with Xcode 5 is to install a GCC and direct GHC at that. See this page for instructions.
As Jon Purdy says, this has to do with the preprocessing. In particular, some of the modules in vector-space have their list of required language extensions on top like this:
{-# LANGUAGE MultiParamTypeClasses, TypeOperators
, TypeFamilies, UndecidableInstances, CPP
, FlexibleContexts
#-}
{-# OPTIONS_GHC -Wall #-}
----------------------------------------------------------------------
-- |
-- Module : Data.VectorSpace
...
i.e. a {#- ... -#} over multiple lines, and the delimiter is thus a line starting with #. Which then triggers the preprocessor, to obviously no good result!
You can change this to
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
or probably this will also do:
{-# LANGUAGE MultiParamTypeClasses, TypeOperators
, TypeFamilies, UndecidableInstances, CPP
, FlexibleContexts #-}
Here's a script that does this transformation automatically:
import System.IO.Strict as S
import System.Environment
import Control.Monad
rmLeadHash :: [String] -> [String]
rmLeadHash [] = []
rmLeadHash [l] = [l]
rmLeadHash (l:l':ls)
| ('#':_) <- dropWhile (==' ') l' = (l ++ l') : rmLeadHash ls
| otherwise = l : rmLeadHash (l':ls)
main = do
files <- getArgs
forM_ files $ \f -> do
hs <- S.readFile f
writeFile f $ unlines . rmLeadHash . lines $ hs
You can with this do
$ git clone git://github.com/conal/vector-space.git # or cabal fetch vector-space
$ cd vector-space
$ cabal install strict # needed for my script
$ find src -name '*.hs' | xargs runhaskell remLeadingHashes.hs
# ^- the script I've posted
$ cabal install # installs the modified vector-space package
If it works, you may want to push the changes.

How can I import a Haskell module in GHCi?

I am trying to teach myself Haskell from the book Learn You A Haskell for Great Good. I got up to the last section of chapter 7 (Modules), where it tells how to create your own module. I did a copy and paste of the Geometry module given in the book at the beginning of the section. The name of the file is Geometry.hs, as the book suggested, and the file is in the bin directory for ghci, which is where I previously was able to successfully do a load using :l for another .hs file.
When I type the following command in GHCi
import Geometry
I get the following error:
Could not find module 'Geometry' It is not a module in the current
program or in any known package
I must be doing something that is obviously wrong, but I can't figure out what it is.
When you use import ModuleName in GHCi, it works (mostly) in the same way import Data.List works: GHC checks your local package database for the module, loads it, and brings its (exported) contents into scope.
However, Geometry isn't a module of a package installed with ghc-pkg. Therefore, GHC doesn't know that a module Geometry exists at all. Neither does it interactive variant GHCi.
But if you :load a program, things change. GHC will take its used modules into account:
-- Foo.hs
module Foo where
foo :: IO ()
foo = putStrLn "Hello from foo!"
-- Main.hs
module Main where
import Foo (foo)
main :: IO ()
main = foo
$ cd /path/to/your/files
$ ghci
GHCi, version 7.10.2: http://www.haskell.org/ghc/ :? for help
Prelude> import Foo
<no location info>:
Could not find module ‘Foo’
It is not a module in the current program, or in any known package.
Prelude> :l Main.hs
[1 of 2] Compiling Foo ( Foo.hs, interpreted )
[2 of 2] Compiling Main ( Main.hs, interpreted )
Ok, modules loaded: Main, Foo.
*Main> :l Main.hs
*Main> foo
Hello from foo!
*Main> import Foo
*Main Foo> -- module now loaded
As you can see, importing Foo first failed. However, after we've actually loaded the program that uses Foo, we were able to use import Foo in GHCi.
So if you want to use import in GHCi, make sure that GHC can find your module, either by including it in a wrapper or installing it. If you just want to load the module itself, use :load.
TLDR: the Learn you a Haskell book fails to mention that you have to :load the Geometry.hs file first. Then :m to go back to Prelude and then import Geometry works.
It is now also possible to add the lib flag when installing packages, i.e. to run cabal install --lib packagename and then to import the corresponding package directly in GHCi. In the present case, for example cabal install --lib hgeometry would facilitate importing modules from this geometry package.

Resources