Haskell package vector-space fails at compile time

2019-07-17 18:55发布

问题:

I tried to install the Haskell diagrams library and one of the dependencies cannot be installed. Being not that experienced to haskell, I cannot quite see how to resolve this error.

I removed warnings that I believe are not related to the failed build (------ warnings ommitted (-Winvalid-pp-token) -----)

[hsenv]➜  ~HSENV    cabal install vector-space-0.8.5
Resolving dependencies...
Downloading vector-space-0.8.5...
Configuring vector-space-0.8.5...
/var/folders/nq/fx4vf3v14jz9b8mldvcyv1xr0000gn/T/23218.c:1:12:
     warning: control reaches end of non-void function [-Wreturn-type]
int foo() {}
           ^
1 warning generated.
Building vector-space-0.8.5...
Preprocessing library vector-space-0.8.5...

------ warnings ommitted (-Winvalid-pp-token) -----

src/Data/VectorSpace.hs:4:3:
     error: invalid preprocessing directive
     #-}
      ^
------ warnings ommitted (-Winvalid-pp-token) -----
2 warnings and 1 error generated.
Failed to install vector-space-0.8.5
cabal: Error: some packages failed to install:
vector-space-0.8.5 failed during the building phase. The exception was:
ExitFailure 1

回答1:

I presume you’re on OS X with Xcode 5 installed? There are instructions for that.

Xcode 5 supplies Clang as the C compiler, and with respect to pre-processing there are some “differences of interpretation” between it and GCC. These differences can affect some Haskell code that uses the CPP extension. An alternate approach for users with Xcode 5 is to install a GCC and direct GHC at that. See this page for instructions.



回答2:

As Jon Purdy says, this has to do with the preprocessing. In particular, some of the modules in vector-space have their list of required language extensions on top like this:

{-# LANGUAGE MultiParamTypeClasses, TypeOperators
           , TypeFamilies, UndecidableInstances, CPP
           , FlexibleContexts
 #-}
{-# OPTIONS_GHC -Wall #-}
----------------------------------------------------------------------
-- |
-- Module      :   Data.VectorSpace
...

i.e. a {#- ... -#} over multiple lines, and the delimiter is thus a line starting with #. Which then triggers the preprocessor, to obviously no good result!

You can change this to

{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeOperators         #-}
{-# LANGUAGE TypeFamilies          #-}
{-# LANGUAGE UndecidableInstances  #-}
{-# LANGUAGE CPP                   #-}
{-# LANGUAGE FlexibleContexts      #-}

or probably this will also do:

{-# LANGUAGE MultiParamTypeClasses, TypeOperators
           , TypeFamilies, UndecidableInstances, CPP
           , FlexibleContexts #-}

Here's a script that does this transformation automatically:

import System.IO.Strict as S
import System.Environment
import Control.Monad

rmLeadHash :: [String] -> [String]
rmLeadHash [] = []
rmLeadHash [l] = [l]
rmLeadHash (l:l':ls)
  | ('#':_) <- dropWhile (==' ') l'  = (l ++ l') : rmLeadHash ls
  | otherwise                        = l : rmLeadHash (l':ls)

main = do
   files <- getArgs
   forM_ files $ \f -> do
      hs <- S.readFile f
      writeFile f $ unlines . rmLeadHash . lines $ hs

You can with this do

$ git clone git://github.com/conal/vector-space.git  # or cabal fetch vector-space
$ cd vector-space
$ cabal install strict     # needed for my script
$ find src -name '*.hs' | xargs runhaskell remLeadingHashes.hs
                                  #              ^- the script I've posted
$ cabal install     # installs the modified vector-space package

If it works, you may want to push the changes.



标签: haskell cabal