Yesod wai-eventsource example. Package dependency issue? - haskell

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.

Related

Duplicate packages in Haskell environment?

I put this in a file (see bottom) and got the following error when loading it in ghci (i.e. start ghci then :l file):
7:13: error:
• Couldn't match expected type ‘network-uri-2.6.1.0#network-uri-2.6.1.0-7BN1tbB3iHQ2XgvmqLAYph:Network.URI.URI’
with actual type ‘Network.URI.URI’
NB: ‘Network.URI.URI’
is defined in ‘Network.URI’
in package ‘network-uri-2.6.1.0#network-uri-2.6.1.0-80FpvaNUTSDFCPv0sSze40’
‘network-uri-2.6.1.0#network-uri-2.6.1.0-7BN1tbB3iHQ2XgvmqLAYph:Network.URI.URI’
is defined in ‘Network.URI’
in package ‘network-uri-2.6.1.0#network-uri-2.6.1.0-7BN1tbB3iHQ2XgvmqLAYph’
Have I somehow installed two slightly different versions of network-uri, or what is this? How do I resolve it?
I've hardly used cabal but tried cabal install --reinstall network-uri, went fine but problem persists.
File contents:
import Network.HTTP
import Network.URI (parseURI)
import Data.Maybe (fromJust)
myRequestURL = "http://www.virginia.edu/cgi-local/ldapweb"
myRequest :: String -> Request_String
myRequest query = Request {
rqURI = fromJust $ parseURI myRequestURL
, rqMethod = POST
, rqHeaders = [ mkHeader HdrContentType "text/html"
, mkHeader HdrContentLength $ show $ length body ]
, rqBody = body
}
where body = "whitepages=" ++ query
main :: IO ()
main = do
response <- simpleHTTP $ myRequest "poon"
putStrLn ""
EDIT Re-installed haskell-platform. After this, ghc-pkg list reports all packages to be under (?) /usr/lib/ghc/package.conf.d, and the program I tried to copy loads just fine.
EDIT 2 After running cabal install some-pkg, ghc-pkg list reports that the newly installed stuff is in another directory. Indeed, ~/.cabal/config specifies install dirs for user, as well as install dirs for global. How is all this supposed to be managed properly?
GHC understands the concept of package databases. Cabal manages multiple package databases. There's a system package database, and a user package database. When you compile something with Cabal V1, it uses the union of these package databases. This is a bit of a time bomb, because, as you see, GHC does not like it when you have multiple of the same package. When you issued cabal install network-uri, cabal decided to install one copy of that package into your user database, though you already had one in the system database. When you tried to use ghc, it picked up on the two copies and got confused. Because cabal does not support removing packages, your Haskell installation was pretty much borked, and you reinstalled. I believe you could have done a more conservative rm ~/.ghc, or, had you been really adventurous, used the low-level ghc-pkg command to edit the package database.
Now that you've reinstalled the Platform, I would heavily recommend never using cabal install again. It's old, it's broken, cabal itself tells you not to use it. If you're using the Platform, I think it has stack in it, which is a different build manager, based on Cabal, which is not prone to this kind of breakage. Or, you can just stick to the V2 series of cabal commands, which is what I prefer.
Cabal V2 does not directly support your usecase, where you install a package globally and compile a program against it. This is because doing so is fundamentally broken: global package databases really just don't work for GHC. What Cabal V2 does is install packages into your home directory, ~/.cabal/store. You then have to explicitly tell it which packages you want, and it will construct a package database that contains each required package, without any wonkiness. You can get a REPL with a certain set of packages by issuing (this will take you to a temporary directory; you may need to :cd yourself back.)
cabal v2-repl -b network-uri -b package2 -b etc
If you want to actually compile files with ghc with a set packages, you have to actually define a package with a .cabal file. Here's a stub .cabal file:
name: temporary-pkg
version: 0.0.0.0
build-type: Simple
cabal-version: >=2.0
executable main -- if there is no Main, say "library" instead of "executable <name>"
default-language: Haskell2010
main-is: Main.hs -- only valid in executable stanzas
hs-source-dirs: src -- source files go here
build-depends: base, network-uri, package2, etc -- packages go here
Create and enter a directory, place that in temporary-pkg.cabal, place your sources in src/, and you can issue stuff like cabal v2-build and cabal v2-repl and cabal v2-exec main, etc. cabal will go off and install dependencies from Hackage into ~/.cabal/store as needed. cabal v2-install is therefore not that useful here. In general, v2-installing libraries is unnecessary, but v2-installing packages with executables is useful. Again, for hygiene reasons, you have to list all the packages you are importing from, but you don't need to list their dependencies or anything insane like that.
Cabal V2 still doesn't support uninstalling packages, though the point is that should not be necessary. However, if you find ~/.cabal/store getting too large for your liking, you can just nuke it, and should be built back up as packages are requested.

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.

type mismatch on Network.Wai.Middleware

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.

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

Snap: Params type error

I get this type error:
Couldn't match type `containers-0.5.0.0:Data.Map.Base.Map
ByteString [ByteString]'
with `M.Map ByteString [ByteString]'
Expected type: M.Map ByteString [ByteString]
Actual type: Params
But Params type is Map ByteString [ByteString]
type Params = Map ByteString [ByteString]
If it is of any help, this is the full function:
import qualified Data.Map as M
categoryDoc :: Params -> Document
categoryDoc params = map (\(k,[v]) -> T.decodeUtf8 k =: T.decodeUtf8 v) $ M.toList params
Thank you.
You have encountered cabal hell.
The problem is that there are multiple versions of the containers package installed. This means that there are two versions of the Map data type, one from containers-0.5.0.0 and one from the other version. Those two won't match, and that's why you get the error.
The easiest solution to that problem is to delete the ~/.ghc (on unix) directory and rebuilt everything. But that won't protect you from such problems in future, and there is also a chance that it won't work at all. So this is not a good solution.
If you have cabal-install of at least version 1.18, you can use the cabal sandboxes feature. This allows you to create an isolated package environment for each project, and thus avoid such conflicts. Just switch to your project and run:
cabal sandbox init # Create a new sandbox
cabal install --only-dependencies # Install dependencies
cabal build # Build your project
You can also use cabal install to install your project into the sandbox or cabal repl to start GHCi with the right settings for your project.
If you do not have a new-enough version of cabal-install and can't upgrade, you can use cabal-dev to create and manage sandboxes.

Resources