2016-09-02 33 views
9

Mam stary kod, który był używany do kompilacji, ale teraz tak nie jest. Obawiam się, że mogłem trafić na snafu z zarządzania pakietami i naprawdę nie mogę sobie z tym poradzić. Zredukowalem to do minimalnego nieudanego przykładu.Jak udało się zniknąć z instancji (Param B.ByteString)?

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

Błąd pojawia się

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

Ale kiedy patrzę na kod źródłowy dla

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

widzę

import qualified Data.ByteString as SB 

i

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

Stosowna informacja wersja może zawierać

$ 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 

Kiedy pytam ghci

:info Param 

uzyskać krótszy niż wykaz dokumentacji MySQL proste doprowadzi mnie oczekiwać.

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’ 

, ale przypuszczam, że tylko informuje mnie o przypadkach dla zakresu lokalnie w zakresie. I wtedy zrobić

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

kolejne punkty dochodzenia do potencjalnego źródła kłopotów:

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

Zgaduję, że ByteString z instancją jest od 0.10.6.0 i różnią się od wersji otrzymuję dokładnie podczas zapisu ten sam import w moim pliku źródłowym. Jeśli tak, to jestem trochę zirytowany tym, jak wiele pracy musiałem zrobić, aby to odkryć: byłoby świetnie, gdyby "Żadna instancja dla Foo" nie dodałaby "mimo, że istnieje instancja dla całego innego Foo".

To jest piekło cabal, prawda? Czy mogę dokonać prostej odbudowy mysql w nowszej wersji? Próbowałem ghc-pkg unregister mysql-simple, a następnie cabal install mysql-simple, ale bezskutecznie.

Jaka jest dobra strategia naprawy?

+0

Czy próbowałeś skompilować swój kod w czystej piaskownicy cabal? – redneb

+0

Nie jestem ekspertem od tego, dlaczego takie rzeczy się zdarzają, ale zazwyczaj podaję listę potrzebnych pakietów i problematyczny pakiet z konkretną wersją, której potrzebuję. Tak więc 'cabal install mysql-simple bytestring-0.10.8.1'. Zwykle działa albo daje mi lepszy powód, dla którego nie zadziała. – fryguybob

+0

@redneb Nie korzystałem z piaskownicy, ale musiałem zainstalować mysql-simple i utf8-bytestring. I zrobiłem to w tej kolejności. Wydaje mi się, że mogło już istnieć dawne świadectwo przeszłości, ale to utf8-bytestring mogło doprowadzić do nowego, jak katastrofa bez ostrzeżenia. – pigworker

Odpowiedz

3

Jaka jest dobra strategia naprawy?

Zachęcam do kabalizacji kodu i używania piaskownicy kabalowej lub stack. To powinno przede wszystkim zapobiegać problemowi. Aby naprawić, powinieneś dowiedzieć się, jaki pakiet jest zainstalowany dwukrotnie (wydaje się być bytestring) i wyrejestrować go.

Jestem trochę wkurzona na ile pracy musiałem zrobić, żeby się tego dowiedzieć: byłoby wspaniale, gdyby „Nie instancja dla Foo” doda „choć nie jest to instancja dla całej drugiej Foo” .

I know co czujesz.Na szczęście jest już fixed, więc powinieneś dostać lepszy komunikat o błędzie z ghc-8

+0

Świetnie! Z niecierpliwością czekam na uaktualnienie do wersji ghc 8, co zrobię, gdy tylko poprawka https://ghc.haskell.org/trac/ghc/ticket/12007 będzie dostępna. Żądanie jednoczesnej instalacji cab mysql-simple i nowszego testowania sprawiło, że wyskoczyłem z dziury. Cabalizowanie mojego raczej małego programu z jednym tylko lokalnie specjalnym przeznaczeniem znacznie zwiększyłoby koszty ogólne. – pigworker