type mismatch on Network.Wai.Middleware - haskell

I am trying to follow this post to serve static files with scotty. So I have this small script:
{-# LANGUAGE OverloadedStrings #-}
import Web.Scotty
import Network.Wai.Middleware.Static
import Data.Monoid (mconcat)
main = scotty 3000 $ do
middleware $ staticPolicy (noDots >-> addBase "static")
get "/:word" $ do
beam <- param "word"
html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"]
Running ghc yields the following error:
server.hs:9:16:
Couldn't match type `Network.Wai.Internal.Request'
with `wai-1.4.0.1:Network.Wai.Request'
Expected type: wai-1.4.0.1:Network.Wai.Middleware
Actual type: Network.Wai.Middleware
In the return type of a call of `staticPolicy'
In the second argument of `($)', namely
`staticPolicy (noDots >-> addBase "static")'
In a stmt of a 'do' block:
middleware $ staticPolicy (noDots >-> addBase "static")
Now I don't understand how to interpret wai-1.4.0.1:Network.Wai.Middleware vs Network.Wai.Middleware. Is it a version issue? I tried checking the library installed, but I could not find any conflict.
What should I check to solve this?
Edit
Running ghc-pkg list wai gives me:
C:\perso\prog\haskell\orgmode\orgmodeserver\src\hs>ghc-pkg list wai
WARNING: there are broken packages. Run 'ghc-pkg check' for more details.
C:/Program Files (x86)/Haskell Platform/2013.2.0.0\lib\package.conf.d:
C:\Users\sberg\AppData\Roaming\ghc\i386-mingw32-7.6.3\package.conf.d:
wai-1.4.0.1
wai-2.0.0
Running ghc-pkg check (skipping a bunch of warnings):
The following packages are broken, either because they have a problem
listed above, or because they depend on a broken package.
scion-browser-0.2.17
miamtime-0.0.0
TestYes-0.0.0
yesod-platform-1.2.2
yesod-1.2.1.1
yesod-auth-1.2.0.2
yesod-form-1.3.0.1

There are probably a dozen different ways to fix this, but the simplest solution is to unregister all the broken packages, unregister both version of wai and install all the packages again, making sure you are not installing 2 versions of wai. Use the flag --dry-run to make sure cabal install isn't installing the old version. If it decides it needs 1.4 and can't use 2.0, you may have to use older versions of some packages.

Related

How can I use GHC with a cabal sandbox that's not in the current working directory?

If I create a cabal sandbox with cabal sandbox init, I can use cabal repl or cabal exec ghc(i) to work with those packages without creating a project:
$ mkdir /tmp/example && cd /tmp/example
$ cabal sandbox init
$ cabal install QuickCheck
$ cabal exec ghci
Prelude> :m Test.QuickCheck
Prelude Test.QuickCheck>
However, if I change the path to something else, even to a subdirectory, I cannot access the packages anymore:
$ mkdir -p /tmp/example/sub && cd /tmp/example/sub
$ cabal exec ghci
Prelude> :m Test.QuickCheck
<no location info>:
Could not find module ‘Test.QuickCheck’
It is not a module in the current program, or in any known package.
Is there any way to use the contents from the sandbox, without copying its content?
The problem is that cabal will only respect sandboxes in the current working directory. However, there are several options where you can specify a sandbox location for cabal or the package databse for GHC.
Using cabal features
You can use cabal's --sandbox-config-file option to specify a sandbox configuration, e.g.
$ cabal --sandbox-config-file=/tmp/example/cabal.sandbox.config exec ghci
Prelude> :m Test.QuickCheck
Prelude Test.QuickCheck>
This also enables you to change the sandbox from other places, which comes in handy if you just want to install random stuff into a temporary place:
$ cabal --sandbox-config-file=/tmp/example/cabal.sandbox.config install lens
$ cabal --sandbox-config-file=/tmp/example/cabal.sandbox.config repl
Prelude> :m Control.Lens
Prelude Control.Lens> :m Test.QuickCheck
Prelude Control.Lens Test.QuickCheck>
Since this gets cumbersome after a while, you should probably add an alias
$ alias sandboxed-cabal="cabal --sandbox-config-file=/tmp/example/cabal.sandbox.config"
$ sandboxed-cabal repl
Prelude>
Using ghc -package-db
Alternatively, you can directly specify the package database when you use GHC with -package-db:
$ ghci -package-db /tmp/example/.cabal-sandbox/<ARCH>-packages.conf.d
Prelude> :m Test.QuickCheck
Prelude Test.QuickCheck>
The <ARCH> depends on your system and the used GHC, e.g. on a 64bit Linux and GHC 7.10.3 it's x86_64-linux-ghc-7.10.3-packages.conf.d. You can then use all packages in that database:
$ ghci -package-db /tmp/example/.cabal-sandbox/<ARCH>-packages.conf.d
Prelude> :m Control.Lens
Prelude Control.Lens>
Again, an alias should come in handy.
Using GHC_PACKAGE_PATH
Last, but not least, you can adjust an environment variable. However, if the environment variable GHC_PACKAGE_PATH exists, it will overwrite GHC's usual package databases, so you either need to check ghc-pkg list and add them too
$ GHC_PACKAGE_PATH=/opt/ghc/7.10.3/lib/ghc-7.10.3/package.conf.d/:/tmp/example/.cabal-sandbox/x86_64-linux-ghc-7.10.3-packages.conf.d ghci
or use -global-package-db and -user-package-db to reenable them:
$ GHC_PACKAGE_PATH=/tmp/example/.cabal-sandbox/x86_64-linux-ghc-7.10.3-packages.conf.d ghci -global-package-db -user-package-db

Type mismatch after cabal update?

Program has the following import:
import Pipes.Network.TCP
import Pipes
import Pipes.Core
import qualified Data.ByteString.Char8 as C
Compilation fails like so:
Couldn't match expected type `bytestring-0.9.2.1:Data.ByteString.Internal.ByteString'
with actual type `C.ByteString'
Expected type: Proxy
Int
bytestring-0.9.2.1:Data.ByteString.Internal.ByteString
()
b0
m0
()
Actual type: Proxy Int C.ByteString () C.ByteString IO ()
I can be more specific about the code, but it looks like this is not related to code - rather some cabal whim. Perhaps, Pipes that I import are considered to use a different ByteString than the one imported with qualified name.
The program used to compile some time ago (I have its working executable), but now it stopped, and I suspect there could have been some cabal update or package installation. How to debug and fix this?
Assuming your program is built with cabal, you should re-configure it. This may highlight other problems, such as dependencies which would require re-installing or breaking other parts of the dependency tree. The "old way" to solve this is to progressively cabal install more and more things until the dependency solver agrees it's possible, e.g.
$ cabal install .
# complains that reinstalls might break lens
$ cabal install . lens
# complains that reinstalls might break bytestring
$ cabal install . lens bytestring
# complains that reinstalls might break X
$ cabal install . lens bytestring X
...etc. The "new way" is to use no-reinstall cabal. You will still need to reconfigure before you build, and may need to install some dependencies again to transition properly.

cabal benchmark bytestring: package has no benchmark

When I tried to run cabal benchmark on bytestring I got package has no benchmark. Indeed, the .cabal file does not have benchmark configs. But the repo does have a bench directory. How does this work? Should I not try to benchmark it?
edit:
When running cabal build in the bench directory I got the following error:
Building bench-bytestring-0.1.0.0...
Preprocessing executable 'bench-bytestring-builder' for
bench-bytestring-0.1.0.0...
[18 of 18] Compiling Main ( BenchAll.hs, dist/build/bench-bytestring-builder/bench-bytestring-builder-tmp/Main.o )
BenchAll.hs:133:46:
Couldn't match expected type ‘Benchmarkable’
with actual type ‘IO ()’
In the second argument of ‘($)’, namely ‘benchIntEncodingB nRepl e’
In the expression:
bench (name ++ " (" ++ show nRepl ++ ")")
$ benchIntEncodingB nRepl e
The bench directory has a separate Cabal file, bench-bytestring.cabal. You should be able to cd into that directory and do cabal run to run the benchmarks.
That package's description explains why it works this way:
This package is not meant for public release. It fixes a problem with the current benchmarking support in cabal, which has trouble compiling because criterion depends on bytestring. Here, we just include the whole source of the bytestring library directly.

Compile error in Wai installing Yesod on OS X

I'm pretty new to Haskell, and trying to install Yesod with Cabal, but I'm running into this compilation error:
cabal install yesod --force-reinstalls
Network/Wai/Parse.hs:106:61:
No instance for (Control.Monad.Trans.Resource.Internal.MonadThrow
(ConduitM S8.ByteString Void IO))
arising from a use of `allocate'
Possible fix:
add an instance declaration for
(Control.Monad.Trans.Resource.Internal.MonadThrow
(ConduitM S8.ByteString Void IO))
In the second argument of `($)', namely
`allocate
(do { tempDir <- getTmpDir;
openBinaryTempFile tempDir pattern })
(\ (_, h) -> hClose h)'
In a stmt of a 'do' block:
(key, (fp, h)) <- flip runInternalState internalState
$ allocate
(do { tempDir <- getTmpDir;
openBinaryTempFile tempDir pattern })
(\ (_, h) -> hClose h)
In the expression:
do { (key, (fp, h)) <- flip runInternalState internalState
$ allocate
(do { tempDir <- getTmpDir;
openBinaryTempFile tempDir pattern })
(\ (_, h) -> hClose h);
_ <- runInternalState (register $ removeFile fp) internalState;
CB.sinkHandle h;
lift $ release key;
.... }
Failed to install wai-extra-2.0.2
This is the full output when installing
I'm using the latest Haskell Platform with the ghc-clang-wrapper script.
Cabal versions:
$ cabal --version
cabal-install version 1.16.0.2
using version 1.16.0 of the Cabal library
GHC version:
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.6.3
Some of the tutorials mention using a cabal sandbox, but my version of cabal (1.16) is too old for that. If the sandbox is likely too help I'll try and get that working (had a little trouble updating cabal to 1.18).
It looks like you have several modules which when installed beside existing modules cause name collisions. Further up in the output before the error you posted there are a bunch of errors like this:
Network/HTTP/Client/Conduit.hs:37:9:
Ambiguous occurrence `MonadResource'
It could refer to either `Data.Conduit.MonadResource',
imported from `Data.Conduit' at Network/HTTP/Client/Conduit.hs:13:1-19
(and originally defined in `resourcet-0.4.10:Control.Monad.Trans.Resource.Internal')
or `Control.Monad.Trans.Resource.MonadResource',
imported from `Control.Monad.Trans.Resource' at Network/HTTP/Client/Conduit.hs:15:1-35
(and originally defined in `Control.Monad.Trans.Resource.Internal')
These may be caused by --force-reinstalls. This is basically what cabal sandbox was created for so it may be easier to post a question about whatever is going wrong in updating that. You should be able to cabal install cabal-install to update it to the newest version.
Edit:
If cabal install cabal-install is working then the first thing I would check, as Chrules mentions, is where your path is pointed at. When you install cabal via cabal it will get put in ~/.cabal/bin so that needs to be first in your path. If you do which cabal you'l probably now see something like /usr/bin/cabal, you want that to be ~/.cabal/bin/cabal. Since you're local user packages are now messed up anway here's what I would do.
rm -rf ~/.cabal ~/.ghc # This deletes everything you installed with cabal
cabal update # Reinitialize the platform cabal
cabal install cabal-install # Update cabal
cabal install yesod # This will work since you nuked your ~/.cabal and ~/.ghc
After doing this you will have nothing installed but yesod, and you probably want yesod-bin as well since that has the yesod binary (at ~/.cabal/bin).

Yesod wai-eventsource example. Package dependency issue?

I'm trying to get this example code to compile on my system.
When I try to compile the Chat module with ghc Chat.hs, ghc gives me this:
Chat.hs:76:39:
Couldn't match expected type `Network.Wai.Request'
with actual type `wai-0.4.3:Network.Wai.Request'
In the second argument of `eventSourceApp', namely `req'
In the second argument of `($)', namely `eventSourceApp chan req'
In a stmt of a 'do' expression:
res <- lift $ eventSourceApp chan req
I am on OS X Snow Leopard and cleared up (everything?) except the Haskell Platform like this:
rm -r ~/.cabal
rm -r ~/.ghc
rm -r ~/Library/Haskell
and installed yesod and wai-eventsource anew from hackage.
As far as I understand the error comes from a dependency problem.
wai
Synopsis: Web Application Interface.
Default available version: 1.0.0
Installed versions: 0.4.3, 1.0.0
Homepage: https://github.com/yesodweb/wai
License: BSD3
Where yesod-0.9.4.1 requires wai == 0.4.* and wai-eventsource-1.0.0 requires wai >= 1.0.
So, my question would be: Is it possible to get this example (with the official releases of yesod) to work right now? With all the change the yesod project is going through atm?
Do I have to be more precise on the versions I try to install and, if so, how?
Edit:
I wiped out ~/.ghc (or actually followed a more rigorous approach given here, just in case) and tried to install the packages with a single
cabal install yesod wai-eventsource resulting in (incomplete):
Resolving dependencies...
cabal: cannot configure yesod-0.9.4.1. It requires wai ==0.4.* and warp ==0.4.*
For the dependency on wai ==0.4.* there are these packages: wai-0.4.0,
wai-0.4.1, wai-0.4.2 and wai-0.4.3. However none of them are available.
wai-0.4.0 was excluded because wai-eventsource-1.0.0 requires wai >=1.0
...
wai-0.4.3 was excluded because wai-eventsource-1.0.0 requires wai >=1.0
For the dependency on warp ==0.4.* there are these packages: warp-0.4.0,
warp-0.4.0.1, warp-0.4.1, warp-0.4.1.1, warp-0.4.1.2, warp-0.4.2, warp-0.4.3,
warp-0.4.3.1, warp-0.4.4, warp-0.4.5, warp-0.4.6, warp-0.4.6.1, warp-0.4.6.2
and warp-0.4.6.3. However none of them are available.
warp-0.4.0 was excluded because wai-eventsource-1.0.0 requires warp >=1.0
...
warp-0.4.6.3 was excluded because wai-eventsource-1.0.0 requires warp >=1.0
Before that (with yesod and wai-eventsource installed separately) I tried ghc -hide-package wai-1.0.0 Chat.hs resulting in,
Chat.hs:77:39:
Couldn't match expected type `wai-1.0.0:Network.Wai.Request'
with actual type `Network.Wai.Request'
In the second argument of `eventSourceApp', namely `req'
In the second argument of `($)', namely `eventSourceApp chan req'
In a stmt of a 'do' expression:
res <- lift $ eventSourceApp chan req
I think you need to unregister (or hide) wai 1.0.0. The current Yesod is using wai 0.4, which is where the mismatch is coming from. (Once a newer Yesod is released, this problem will disappear.)
Alternatively, you could wipe out your ~/.ghc folder again and run cabal install yesod wai-eventsource, which should automatically install only the compatible versions.
Edit: You need to hide wai-eventsource as well, and possibly a few others. And simplest approach is to run ghc-pkg unregister wai-eventsource-1.0.0 --force.

Resources