9

I have some old code which used to compile, but now it doesn't. I worry I may have hit a package management snafu, and I'm really bad at dealing with that sort of thing. I've cut it down to a minimal failing example.

{-# LANGUAGE OverloadedStrings #-}

module Gremlin where

import Database.MySQL.Simple.Param
import qualified Data.ByteString as SB

foo :: Param x => [x]
foo = []

shoo :: [SB.ByteString]
shoo = foo

The error I get is

/.../Gremlin.hs:12:8:
No instance for (Param SB.ByteString) arising from a use of ‘foo’
In the expression: foo
In an equation for ‘shoo’: shoo = foo

But when I look at the source code for

module Database.MySQL.Simple.Param
    (
      Action(..)
    , Param(..)
    , inQuotes
    ) where

I see

import qualified Data.ByteString as SB

and

instance Param SB.ByteString where
    render = Escape
    {-# INLINE render #-}

Relevant version information may include

$ ghci --version
The Glorious Glasgow Haskell Compilation System, version 7.10.2
$ ghc-pkg latest mysql-simple
mysql-simple-0.2.2.5
$ ghc-pkg latest bytestring
bytestring-0.10.8.1

When I ask ghci

:info Param

I get a shorter list than the mysql-simple documentation would lead me to expect.

Prelude> :m + Database.MySQL.Simple.Param Data.ByteString
Prelude Database.MySQL.Simple.Param Data.ByteString> :info Param
class Param a where
  render :: a -> Action  
    -- Defined in ‘Database.MySQL.Simple.Param’
instance Param [Char] -- Defined in ‘Database.MySQL.Simple.Param’
instance Param Word -- Defined in ‘Database.MySQL.Simple.Param’
instance Param a => Param (Maybe a)
  -- Defined in ‘Database.MySQL.Simple.Param’
instance Param Integer -- Defined in ‘Database.MySQL.Simple.Param’
instance Param Int -- Defined in ‘Database.MySQL.Simple.Param’
instance Param Float -- Defined in ‘Database.MySQL.Simple.Param’
instance Param Double -- Defined in ‘Database.MySQL.Simple.Param’
instance Param Bool -- Defined in ‘Database.MySQL.Simple.Param’
instance Param Action -- Defined in ‘Database.MySQL.Simple.Param’

but I suppose that only tells me the instances for what's locally in scope. I then do

Prelude Database.MySQL.Simple.Param Data.ByteString> :m +Data.Text
Prelude Database.MySQL.Simple.Param Data.ByteString Data.Text> :info Param
class Param a where
...
instance Param Text -- Defined in ‘Database.MySQL.Simple.Param’
...

Further investigation points to a potential source of trouble:

$ ghc-pkg describe mysql-simple
name: mysql-simple
version: 0.2.2.5
...
depends:
...
    bytestring-0.10.6.0-6e8453cb70b477776f26900f41a5e17a
...

I'm guessing that the ByteString with the instance is from 0.10.6.0 and distinct from the version I get when write exactly the same import in my source file. If so, I'm a bit peeved at how much work I had to do to find that out: it would be great if "No instance for Foo" would add "even though there's an instance for a whole other Foo".

This is cabal hell, right? Can I make mysql-simple rebuild with the newer version? I tried ghc-pkg unregister mysql-simple and then cabal install mysql-simple, but to no avail.

What's a good repair strategy?

pigworker
  • 43,025
  • 18
  • 121
  • 214
  • 1
    Have you tried to compile your code in a clean cabal sandbox? – redneb Sep 02 '16 at 13:34
  • I'm no expert in why these things happen, but I usually list the package I want and the problematic package with the specific version I need. So `cabal install mysql-simple bytestring-0.10.8.1`. This usually either works or gives me a better reason why it won't work. – fryguybob Sep 02 '16 at 13:39
  • @redneb I didn't use a sandbox, but I did have to install mysql-simple and utf8-bytestring. And I did it in that order. I think there may have been an old bytestring there already, but that utf8-bytestring might have brought in the new one, like a no warning disaster. – pigworker Sep 02 '16 at 13:46
  • @fryguybob I just tried that. Hilariously it did a lot more thinking than I expected and decided to do a version bump to pcre-light-0.4.0.4, whose config stage failed because pkg-config could not be found. I don't blame you, ok? – pigworker Sep 02 '16 at 13:57
  • @fryguybob and indeed, a brew install pkg-config later, all was well. Thanks! – pigworker Sep 02 '16 at 14:00

1 Answers1

4

What's a good repair strategy?

I urge you to cabalize the code and use cabal sandbox or stack. It should prevent the issue in the first place. To repair, you should find out what package is installed twice (it seems to be bytestring) and unregister it.

I'm a bit peeved at how much work I had to do to find that out: it would be great if "No instance for Foo" would add "even though there's an instance for a whole other Foo".

I know what you feel. Fortunately it is already fixed, so you should get better error message from ghc-8

Community
  • 1
  • 1
Yuras
  • 13,856
  • 1
  • 45
  • 58
  • Great! I look forward to upgrading to ghc 8, which I will do as soon as this fix https://ghc.haskell.org/trac/ghc/ticket/12007 makes it out there. Demanding simultaneous cabal install of mysql-simple and the newer bytestring got me out of the hole. Cabalizing my rather small only-one-local-special-purpose program would add considerable overhead. – pigworker Sep 02 '16 at 15:14