2016-09-02 2 views
9

Ich habe etwas alten Code, der zum kompilieren verwendet, aber jetzt tut es nicht. Ich mache mir Sorgen, dass ich ein Paketmanagement-Snafu getroffen habe, und ich bin wirklich schlecht darin, mit so etwas umzugehen. Ich habe es auf ein minimales fehlerhaftes Beispiel reduziert.Wie konnte die Instanz (Param B.ByteString) verschwinden?

{-# 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 

Der Fehler, den ich bekommen ist

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

Aber wenn ich auf den Quellcode sucht

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

Ich sehe

import qualified Data.ByteString as SB 

und

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

Relevante Versionsinformationen können

$ 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 

schließen Als ich GHCI fragen

:info Param 

ich eine kürzere Liste als die mysql-einfache Dokumentation bekommen würde mich erwarten lassen.

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’ 

aber ich nehme an, dass nur die Instanzen für das, was lokal im Bereich ist. Ich mache dann

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

Weitere Untersuchungen deutet auf eine potentielle Fehlerquelle:

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

Ich vermute, dass die ByteString mit der Instanz von 0.10.6.0 ist und unterscheidet sich von der Version bekomme ich, wenn Schreib genau der gleiche Import in meiner Quelldatei. Wenn das so ist, bin ich ein bisschen verärgert darüber, wie viel Arbeit ich tun musste, um das herauszufinden: Es wäre großartig, wenn "Keine Instanz für Foo" hinzufügen würde, "obwohl es eine Instanz für ein ganz anderes Foo gibt".

Das ist Kabale Hölle, oder? Kann ich mysql-simple rebuild mit der neueren Version machen? Ich versuchte ghc-pkg unregister mysql-simple und dann cabal install mysql-simple, aber ohne Erfolg.

Was ist eine gute Reparaturstrategie?

+0

Haben Sie versucht, Ihren Code in einer sauberen Cabal Sandbox zu kompilieren? – redneb

+0

Ich bin kein Experte in warum diese Dinge passieren, aber ich liste normalerweise das Paket, das ich will, und das problematische Paket mit der spezifischen Version, die ich brauche. Also 'cabal install mysql-simple bytestring-0.10.8.1'. Dies funktioniert normalerweise entweder oder gibt mir einen besseren Grund, warum es nicht funktioniert. – fryguybob

+0

@redneb Ich habe keine Sandbox benutzt, aber ich musste mysql-simple und utf8-bytestring installieren. Und ich habe es in dieser Reihenfolge gemacht. Ich denke, da war vielleicht schon eine alte Bytestring, aber diese utf8-Bytestring könnte die neue enthalten, wie eine No-Warner-Katastrophe. – pigworker

Antwort

3

Was ist eine gute Reparaturstrategie?

Ich fordere Sie auf, den Code zu cabalize und cabal Sandbox oder stack verwenden. Es sollte das Problem an erster Stelle verhindern. Um zu reparieren, sollten Sie herausfinden, welches Paket zweimal installiert ist (es scheint bytestring zu sein) und die Registrierung aufheben.

Ich bin ein wenig pikiert, wie viel Arbeit, die ich tun musste, um herauszufinden: Es wäre toll, wenn „Nein Beispiel für Foo“ hinzufügen würde „auch wenn es eine Instanz für ein ganz andere Foo“ .

I know was Sie fühlen.Zum Glück ist es schon fixed, also sollten Sie bessere Fehlermeldung bekommen von ghc-8

+0

Großartig! Ich freue mich auf ein Upgrade auf Ghc 8, das ich tun werde, sobald dieses Update https://ghc.haskell.org/trac/ghc/ticket/12007 es schafft. Die anspruchsvolle simultane Installation von mysql-simple und der neueren Bytestring brachten mich aus dem Loch. Die Kabbelei meines eher kleinen Nur-Ein-Ort-Sonderprogramms würde einen erheblichen Mehraufwand bedeuten. – pigworker

Verwandte Themen