I've found that using
me$ stack install --resolver lts-11.0 on the snippet
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
module Main where
import ClassyPrelude
import Network.HTTP.Conduit (host)
hostnameFromUrl :: MonadThrow m => Text -> m Text
hostnameFromUrl url = do
return $ decodeUtf8 $ host "helloworld.com"
fails with message
/Users/me/.../temp/Main.hs:8:20: error:
Not in scope: type constructor or class ‘MonadThrow’
|
8 | hostnameFromUrl :: MonadThrow m => Text -> m Text
| ^^^^^^^^^^
when any lts >= 11.0 is used. No error is raised for lts <= 10.10.
This seems strange, as the relevant package (exceptions-0.8.3) does not change between these two LTSs.
I have stack.yaml file
resolver: lts-11.0
packages:
- '.'
flags: {}
extra-package-dbs: []
and temp.cabal file
name: temp
version: 0.0
build-type: Simple
-- extra-source-files:
cabal-version: >=1.10
library
hs-source-dirs: .
exposed-modules: Main
ghc-options: -Wall
build-depends: classy-prelude >= 1.0.0.2
, http-conduit >= 2.1
default-language: Haskell2010
Pardon the specific setup; I've tried to make this as easily replicable as possible.
Any insight would be greatly appreciated! Thank you.
It's no longer exported from ClassyPrelude, you'd need to import it from Control.Monad.Catch.
Related
I've noticed some really strange behaviour:
I'm trying to get the haskell z3 bindings to work on windows. But if I insert code from the library into the Main module putStrLn stops working. How can that be?
The Setup
I used the precompiled x64 binary of the z3 solver (z3.4.8.4) for windows (and put it in C:\mylibs\z3-4.8.4_x64).
Then I created a stack project haskellZ3Test
The relevant parts from package.yaml:
dependencies:
- base >= 4.7 && < 5
- z3 <= 408.0
The relevant parts from stack.yaml:
resolver: lts-13.28
packages:
- .
- location:
git: https://github.com/IagoAbal/haskell-z3.git
commit: b10e09b8a809fb5bbbb1ef86aeb62109ece99cae
extra-dep: true
extra-include-dirs:
- "C:\\mylibs\\z3-4.8.4_x64\\include"
extra-lib-dirs:
- "C:\\mylibs\\z3-4.8.4_x64\\bin"
The Problem
Here is Main version 1:
module Main where
import Z3.Monad
main :: IO ()
main = putStrLn "hello world"
If I stack build and then stack exec haskellZ3Test-exe I get hello world on the command line as expected.
However - here is Main version 2:
module Main where
import Z3.Monad
ast :: Z3 AST
ast = do
a <- mkFreshBoolVar "A"
b <- mkFreshBoolVar "B"
mkImplies a b
main :: IO ()
main = putStrLn "hello world"
If I stack build and then stack exec haskellZ3Test-exe now I get nothing ...
Honestly I'm pretty puzzled - compiling and linking seems to work fine.
Any help is highly appreciated. Many thanks in advance.
I have two haskell files named SimpleJSON.hs and another is Main.hs
--File: SimpleJSON.hs
module SimpleJSON
(
JValue (..)
,getString
,getInt
,getDouble
,getBool
,getObject
,getArray
,isNull
) where
data JValue = JString String
| JNumber Double
| JBool Bool
| JNull
| JObject [(String, JValue)]
| JArray [JValue]
deriving (Eq, Ord, Show)
And
--File: Main.hs
module Main () where
import SimpleJSON
main = print (JObject [("foo", JNumber 1), ("bar", JBool False)])
So while compiling
I am doing
ghc -c SimpleJSON.hs
and
ghc simple Main.hs SimpleJSON.o
Then I am getting error as
Main.hs:1:1: error:
The IO action ‘main’ is not exported by module ‘Main’
|
1 | module Main () where
| ^
How to resolve this compilation error?
Should be
module Main where
or
module Main (main) where
This answer for specifically for reader of Real World Haskell. It seems that the book uses an older version of Haskell where main need not be explicitly mentioned in the list of exports. In the latest version, this is no longer the case.
There are two aspects that need to be mentioned:
you need to write module Main (main) where so that main is exported
you do not need to make an object file of SimpleJSON.hs and mention it while compiling Main.hs i.e simply running ghc -o simple Main.hs will suffice
As a general note, a couple of reviews on the Amazon page for the book mention that some aspects covered in the book are out of date. So, if you are following this book, make it a point to use another source to catch up on the differences.
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
My Main.hs file takes in commandline arguments:
module Main (toLowerStr, Result(..), grade, main) where
...
grade :: [String] -> String -> String -> (Bool, Result, [Highlight])
grade dictWords correctAnswer studentAnswer =
...
...
main :: IO ()
main = do
args <- getArgs
dict <- readFile $ args !! 0
...
Which works fine, except when I try to test. My testing file is
module Testing where
import Main
import Test.Hspec
main :: IO ()
main = do
dict <- readFile "dict.txt"
let dictWords = map toLowerStr $ lines dict
hspec $ do
describe "Validate passing answers" $ do
it "Match should be verified exactly" $ do
grade dictWords "house" "house"
`shouldBe` (True, Perfect, [])
Yet when I run cabal test it still gives me
Preprocessing test suite 'tests' for grade-0.1.0.0...
[2 of 2] Compiling Testing ( src/HSpecTests.hs, dist/build/tests/tests-tmp/Testing.o )
Linking dist/build/tests/tests ...
Running 1 test suites...
Test suite tests: RUNNING...
tests: Prelude.(!!): index too large
Test suite tests: FAIL
I'm pretty sure it's failing because of the calls to args in Main.main, because the executable itself works fine, and I don't see !! being used anywhere else.
How do I get tests to run?
EDIT: Used pattern matching in Main.hs:
main :: IO ()
main = do
[filename, correctString, studentString] <- getArgs
...
and the error is now
[1 of 2] Compiling Main ( src/Main.hs, dist/build/tests/tests-tmp/Main.o )
Linking dist/build/tests/tests ...
Running 1 test suites...
Test suite tests: RUNNING...
tests: user error (Pattern match failure in do expression at src/Main.hs:141:9-48)
Test suite tests: FAIL
EDIT 2: My entire grade.cabal file
-- Initial grade.cabal generated by cabal init. For further documentation,
-- see http://haskell.org/cabal/users-guide/
name: grade
version: 0.1.0.0
-- synopsis:
-- description:
license-file: LICENSE
author: Amos Ng <amosng#cmu.edu>
maintainer: Amos Ng <amosng#cmu.edu>
-- copyright:
category: Language
build-type: Simple
cabal-version: >=1.8
executable grade
main-is: Main.hs
-- other-modules:
build-depends: base, split ==0.2.*
hs-source-dirs: src
test-suite tests
ghc-options: -Wall
type: exitcode-stdio-1.0
main-is: HSpecTests.hs
other-modules: Main
build-depends: base, split ==0.2.*, hspec ==1.11.*
hs-source-dirs: src
GHC will always use as the entry point the function named main out of the module named Main. Since HSpecTests.hs is the Testing module, not the Main module, its main is completely ignored, instead favoring the main from the Main module. You should break your logic out of the Main module, leaving the Main module as a command-line stub. Then you’ll want to exclude that from the test build, and change module Testing to module Main in HSpecTests.hs.
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.