I'm pretty new to Haskell, and I'm trying to follow along with the Happstack Crash Course. I've done some of the examples, but when I tried the happstack-heist example, I got a strange compilation error. The file that I'm compiling looks like this:
module Main where
import Control.Applicative ((<$>))
import Control.Monad (msum)
import qualified Data.Text as T
import Happstack.Server ( dir, nullConf, nullDir, simpleHTTP
, seeOther, toResponse
)
import Happstack.Server.Heist (heistServe, initHeistCompiled)
import Heist (Splices, (##), getParamNode, noSplices)
import Heist.Compiled (Splice, yieldRuntimeText)
import qualified Text.XmlHtml as X
-- | factorial splice
factSplice :: (Monad m) => Splice m
factSplice = do
intStr <- T.unpack . X.nodeText <$> getParamNode
let res = yieldRuntimeText $ do
case reads intStr of
[(n,[])] ->
return (T.pack $ show $ product [1..(n :: Integer)])
_ ->
return (T.pack $ "Unable to parse " ++
intStr ++ " as an Integer.")
return $ res
main :: IO ()
main = do
heistState <- do
r <- initHeistCompiled (T.pack "fact" ## factSplice) noSplices "."
case r of
(Left e) -> error $ unlines e
(Right heistState) -> return $ heistState
simpleHTTP nullConf $ msum
[ dir "heist" $ heistServe heistState
, nullDir >>
seeOther "/heist/factorial" (toResponse "/heist/factorial")
]
The error is:
test.hs:37:36:
Couldn't match expected type `happstack-server-7.3.9:Happstack.Server.Internal.Types.Response'
with actual type `Happstack.Server.Internal.Types.Response'
In the return type of a call of `toResponse'
In the second argument of `seeOther', namely
`(toResponse "/heist/factorial")'
In the second argument of `(>>)', namely
`seeOther "/heist/factorial" (toResponse "/heist/factorial")'
It seems as though something wants types that are prefixed with the package name and version number, which I don't understand. Both happstack-server and happstack-heist were installed with cabal install.
Welcome to cabal hell! What has happened is that when you installed the two packages for this example,
happstack-serverandhappstack-heist, one of them pulled in a different version of the other than what was already installed on your system. When you tried to compile the example the compiler couldn't figure out which one to use. The solution to this is sandboxes. Justcdto the directory you have this example, runcabal sandbox init, thencabal install --dependencies-only. This will go grab all the dependencies for a project with a.cabalfile and install them in a local.cabal-sandbox/directory. When you runcabal buildorcabal installthe dependencies are pulled from this local folder, and any executable will be installed in.cabal-sandbox/bin.