I have problem using doctest with QuickCheck on NixOS
-- code.hs
--
-- $setup
-- >>> import Test.QuickCheck
--
-- |
-- This test will pass
-- >>> 1 + 1
-- 2
--
-- This test use QuickCheck
-- prob> \xs -> reverse xs = reverse . id $ xs
--
-- The last test will fail to ensure doctest was running
-- >>> 1 == 0
-- True
--
main :: IO ()
main = pure ()
The default haskellPackages.doctest doesn't include QuickCheck
$ nix-shell -p haskellPackages.doctest --run 'doctest code.hs'
code.hs:4: failure in expression `import Test.QuickCheck'
expected:
but got:
<no location info>: error:
Could not find module ‘Test.QuickCheck’
It is not a module in the current program, or in any known package.
Examples: 3 Tried: 1 Errors: 0 Failures: 1
so I try to make an overrride version as mydoctest
# ~/.config/nixpkgs/overlays/doctest.nix
self: super:
with super.haskellPackages;
let
myghc = ghcWithPackages (p: with p;
[
QuickCheck
]);
in
{
mydoctest = doctest.override {
ghc = myghc;
};
}
It still can't find QuickCheck
$ nix-shell -p mydoctest --run 'doctest code.hs'
code.hs:4: failure in expression `import Test.QuickCheck'
expected:
but got:
<no location info>: error:
Could not find module ‘Test.QuickCheck’
It is not a module in the current program, or in any known package.
Examples: 3 Tried: 1 Errors: 0 Failures: 1
but it work if I call it via ghc
$ nix-shell -p mydoctest --run 'ghc -e ":!doctest code.hs"'
code.hs:15: failure in expression `1 == 0'
expected: True
but got: False
Examples: 3 Tried: 3 Errors: 0 Failures: 1
myghc is there but didn't use by mydoctest
$ nix-shell -p mydoctest --run 'doctest --version'
doctest version 0.16.0
using version 8.4.3 of the GHC API
using /nix/store/g1dj8c6h6g8rbb8cv9bgmp1h2f3bxk1l-ghc-8.4.3-with-packages/bin/ghc
$ nix-shell -p mydoctest --run 'which ghc'
/nix/store/qj3vnm903p77nxiraxqxm9b8gbz5rpia-ghc-8.4.3-with-packages/bin/ghc
How can I make doctest to use my override ghc ?
Haskell derivations are not suitable as nix-shell environments by themselves.
The Nixpkgs manual recommends creating a derivation for the purpose of a nix-shell only, using a ghcWithPackages invocation as a dependency.
If the file you're trying to run is part of a haskell package, you can use cabal2nix to do most of the work for you.
I recommend the latter, because it does not pollute your user-wide state (whether profile or user-specific overlay), it is easier to share with others and provides structure that is sufficient to scale from toy example to a valuable package.
I had the same problem trying to get my nix/haskell dev environment set up and found a solution in this reddit post. To get doctest to use a specific version of ghc you can set the environment variable NIX_GHC:
$ doctest --version
doctest version 0.16.3
using version 8.10.3 of the GHC API
using /nix/store/9bm9bs9c4zpl17zdk1d0azid44x3h99b-ghc-8.10.3/bin/ghc-8.10.3
$ export NIX_GHC=/nix/store/zvx9dmfqaa8wibygkbibg4kl98pfj9qv-ghc-8.10.3-with-packages/bin/ghc
$ doctest --version
doctest version 0.16.3
using version 8.10.3 of the GHC API
using /nix/store/zvx9dmfqaa8wibygkbibg4kl98pfj9qv-ghc-8.10.3-with-packages/bin/ghc
Related
I have copied the following code from criterion tutorial:
import Criterion.Main
-- The function we're benchmarking.
fib m | m < 0 = error "negative!"
| otherwise = go m
where
go 0 = 0
go 1 = 1
go n = go (n-1) + go (n-2)
-- Our benchmark harness.
main = defaultMain [
bgroup "fib" [ bench "1" $ whnf fib 1
, bench "5" $ whnf fib 5
, bench "9" $ whnf fib 9
, bench "11" $ whnf fib 11
]
]
I am getting the following error:
fiber.hs:1:1: error:
Could not find module ‘Criterion.Main’
Use -v to see a list of the files searched for.
|
1 | import Criterion.Main
| ^^^^^^^^^^^^^^^^^^^^^
The GHC version I am using is 8.4.2 and cabal version is 2.2.0.0.
I tried to install the criterion package by:
cabal update
Downloading the latest package list from hackage.haskell.org
To revert to previous state run: cabal update --index-state='2018-06-
01T04:23:08Z'
cabal install -j --disable-tests criterion
clang: warning: argument unused during compilation: '-nopie' [-Wunused-
command-line-argument]
.
.
.
.
cabal: Error: some packages failed to install:
abstract-deque-0.3-IvBVpgU2tvq3eILHsBTjFR failed during the building
phase.
The exception was:
ExitFailure 1
aeson-1.3.1.1-J9Jy9Bz77dxJho59OWZvUt depends on aeson-1.3.1.1 which
failed to install.
attoparsec-0.13.2.2-5fvnJr9WRPCJj7fMCLKoI7 depends on attoparsec-
0.13.2.2
which failed to install.
cassava-0.5.1.0-CNxiRQP2h44BSkY7PLw3nv depends on cassava-0.5.1.0 which
failed
to install.
criterion-1.4.1.0-1CDqJgx5SYk1Xphp8S6hvK depends on criterion-1.4.1.0
which failed to install.
microstache-1.0.1.1-DUzquwnO02sC17piNr03EI depends on microstache-
1.0.1.1 which failed to install.
monad-par-0.3.4.8-5Qx7yEAZEkjJbqZykcUjIa depends on monad-par-0.3.4.8
which failed to install.
monad-par-extras-0.3.3-755mClpwIBoBMORFcN7gCY failed during the
building phase. The exception was:
ExitFailure 1
scientific-0.3.6.2-65wDZeAE9ZIBkaesoEq4I0 failed during the building
phase.
The exception was:
ExitFailure 1
statistics-0.14.0.2-GHJ1OiovyXP1FEjV1emzr8 depends on statistics-
0.14.0.2 which failed to install.
text-short-0.1.2-JRY9FeZhxkoAZrj3rm5IJZ failed during the building
phase. The exception was:
ExitFailure 1
uuid-types-1.0.3-tE9Bfk2PgXDUPgbtamBdI failed during the building
phase. The exception was:
ExitFailure 1
One approach would be to use the Stack script interpreter to run this. In order to do so, you would first install Stack, then add the script interpreter bits to the top of your file, e.g.:
#!/usr/bin/env stack
-- stack --resolver lts-11.10 script --optimize
import Criterion.Main
-- The function we're benchmarking.
fib m | m < 0 = error "negative!"
| otherwise = go m
where
go 0 = 0
go 1 = 1
go n = go (n-1) + go (n-2)
-- Our benchmark harness.
main = defaultMain [
bgroup "fib" [ bench "1" $ whnf fib 1
, bench "5" $ whnf fib 5
, bench "9" $ whnf fib 9
, bench "11" $ whnf fib 11
]
]
Note that I added the --optimize option on the second line to ensure that Stack would compile your code with optimizations on, instead of the default of using runghc.
And finally run the file with stack fiber.hs (or whatever you called the file).
I am trying to use hint package from hackage to create a simple environment where user can issue lines of code for evaluation (like in ghci). I expect some of the input lines to be erroneous (eval would end the session with an error). How can I create a robust session that ignores erroneous input (or better: it reports an error but can accept other input) and keeps the previously consistent state?
Also, I would like to use it in do style, i.e. let a = 3 as standalone input line makes sense.
To clarify things: I have no problem with a single eval. What I would like to do, is allow continuing evaluation even after some step failed. Also I would like to incrementally extend a monadic chain (as you do in ghci I guess).
In other words: I want something like this, except that I get to evaluate 3 and don't stop at undefined with the error.
runInterpreter $ setImports [ "Prelude" ] >> eval "undefined" >> eval "3"
More specifically I would like something like this to be possible:
runInterpreter $ setImports ... >> eval' "let a = (1, 2)" -- modifying context
>> typeOf "b" -- error but not breaking the chain
>> typeOf "a" -- (Num a, Num b) => (a, b)
I don't expect it to work this straightforwardly, this is just to show the idea. I basically would like to build up some context (as you do in ghci) and every addition to the context would modify it only if there is no failure, failures could be logged or explicitly retrieved after each attempt to modify the context.
You didn't show any code so I don't know the problem. The most straight-forward way I use hint handles errors fine:
import Language.Haskell.Interpreter
let doEval s = runInterpreter $ setImports ["Prelude"] >> eval s
has resulted in fine output for me...
Prelude Language.Haskell.Interpreter> doEval "1 + 2"
Right "3"
Prelude Language.Haskell.Interpreter> doEval "1 + 'c'"
ghc: panic! (the 'impossible' happened)
(GHC version 7.10.2 for x86_64-apple-darwin):
nameModule doEval_a43r
... Except that now the impossible happens... that's a bug. Notice you are supposed to get Left someError in cases like these:
data InterpreterError
= UnknownError String
| WontCompile [GhcError]
| NotAllowed String
| GhcException String
-- Defined in ‘hint-0.4.2.3:Hint.Base’
Have you looked through the ghchq bug list and/or submitted an issue?
EDIT:
And the correct functionality is back, at least as of GHC 7.10.3 x64 on OS X with hint version 0.4.2.3. In other words, it appears the bug went away from 7.10.2 to 7.10.3
The output is:
Left (WontCompile [GhcError {errMsg = ":3:3:\n No instance for (Num Char) arising from a use of \8216+\8217\n In the expression: 1 + 'c'\n In an equation for \8216e_11\8217: e_11 = 1 + 'c'\n In the first argument of \8216show_M439719814875238119360034\8217, namely\n \8216(let e_11 = 1 + 'c' in e_11)\8217"}])
Though executing the doEval line twice in GHCi does cause a panic, things seem to work once in the interpreter and properly regardless when compiled.
I use cmdargs to write CLI parsers for my Haskell programs.
Let's assume this program, derived directly from their example:
{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs.Implicit
data Sample = Sample {hello :: String} deriving (Show, Data, Typeable)
sample = Sample{hello = def &= help "World argument" &= opt "world"}
&= summary "Sample v1"
main = print =<< cmdArgs sample
If this program is called cmdtest.hs, I can execute
$ runghc cmdtest.hs --hello=world
Sample {hello = "world"}
However, if I leave off the equals sign (like in the -o option in gcc -o foo foobar.c), cmdargs tries to recognize world as a positional argument
$ runghc cmdtest.hs --hello world
Unhandled argument, none expected: world
Is there any option / annotation I can set to allow this syntax in cmdargs?
Update: Using the short option exposes the same problem:
$ runghc cmdtest.hs -h world
Unhandled argument, none expected: world
Update 2: The FlagInfo data in the cmdargs Explicit module seems to suggest it is somehow possible, at least if using Explicit instead of Implicit
Your problem is that you're using opt which makes the value of --hello optional. So --hello world is taken to mean --hello without a value, followed by world as a positional parameter. This is of course a design choice in cmdargs, but I think it's a reasonable one, and it matches the behaviour of most other programs. Take out the opt and see if it works the way you want.
EDIT: Solution: The solution to the problem was to specify the correct vector library in a .cabal file. The tell-tale sign (kindly pointed out by #Daniel below) was that the exact version of the vector was referenced in the error message. Indeed my file was building against vector-0.10.something while vector-fftw was compiled against vector-0.9.1.
I am trying to use the fftw-vector library but am stuck with this type error:
-- test.hs
import qualified Numeric.FFT.Vector.Invertible as FFTI
import qualified Data.Vector.Unboxed as U
z = FFTI.run FFTI.dct1 U.empty
main = putStrLn "Won't compile"
This is the error message:
No instance for (vector-0.9.1:Data.Vector.Generic.Base.Vector
U.Vector Double)
arising from a use of `FFTI.run'
Possible fix:
add an instance declaration for
(vector-0.9.1:Data.Vector.Generic.Base.Vector U.Vector Double)
In the expression: FFTI.run FFTI.dct1 U.empty
In an equation for `z': z = FFTI.run FFTI.dct1 U.empty
but as far as I can tell there is actually an instance of Data.Vector.Gener.Base.Vector for Data.Vector.Unboxed Double (Link) (guess I am wrong).
This is with ghc-7.6.1, vector-0.9.1 and vector-fftw.
(I had to make two tiny changes to vector-fftw so it compiles with base 4.6 and ghc-7.6.1, but that should be unrelated ...)
thank you
EDIT:
two changes I made to vector-fftw:
--- a/Numeric/FFT/Vector/Base.hsc
+++ b/Numeric/FFT/Vector/Base.hsc
## -34,10 +34,11 ## import Control.Monad.Primitive (RealWorld,PrimMonad(..),
import Control.Monad(forM_)
import Foreign (Storable(..), Ptr, unsafePerformIO, FunPtr,
ForeignPtr, withForeignPtr, newForeignPtr)
-import Foreign.C (CInt, CUInt)
+-- import Foreign.C (CInt, CUInt)
import Data.Bits ( (.&.) )
import Data.Complex(Complex(..))
import Foreign.Storable.Complex()
+import Foreign.C.Types
diff --git a/vector-fftw.cabal b/vector-fftw.cabal
index 5ca7c46..0436834 100644
--- a/vector-fftw.cabal
+++ b/vector-fftw.cabal
## -40,7 +40,7 ## Library
Other-modules:
Numeric.FFT.Vector.Base
- Build-depends: base>=4.3 && < 4.6, vector==0.9.*, primitive==0.4.*,
+ Build-depends: base>=4.3 && < 4.7, vector==0.9.*, primitive>=0.4 && < 0.6,
storable-complex==0.2.*
Note that the error message specifies the specific version of the package that defines the class an instance is missing for:
No instance for (vector-0.9.1:Data.Vector.Generic.Base.Vector
U.Vector Double)
That usually means that one of the used packages was compiled against a different version than the one currently used in the project.
I don't see how exactly this would arise, but check for broken packages with ghc-pkg check, and verify that your packages have the correct ids with ghc-pkg describe vector and ghc-pkg describe vector-fftw, possibly vector was rebuilt after building vector-fftw. and the package hashes do not match.
[Source Code]
data FooBar = Foo | Bar
[Command]
$ ghc -c foo_bar.hs
foo_bar.hs:1:0: The function 'main' is not defined in module 'Main'
[Configuration]
Glasgow Haskell Compiler, Version 6.12.3, for Haskell 98, stage 2 booted by GHC
version 6.10.4
You should define your type in a module, and then compile it:
module Test where
data FooBar = Foo | Bar
By invoking ghc -c foo_bar.hs, the object file foo_bar.o will be generated without having to define main.