Search code examples
haskellhappstackheist

Type names prefixed with package name and version


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.


Solution

  • Welcome to cabal hell! What has happened is that when you installed the two packages for this example, happstack-server and happstack-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. Just cd to the directory you have this example, run cabal sandbox init, then cabal install --dependencies-only. This will go grab all the dependencies for a project with a .cabal file and install them in a local .cabal-sandbox/ directory. When you run cabal build or cabal install the dependencies are pulled from this local folder, and any executable will be installed in .cabal-sandbox/bin.