2016-07-01 14 views
1

finden Ich versuche, die Ausführung von etwas Code zur Kompilierungszeit mit GHC 8 und template-haskel-2.11 zu verschieben. Der Code sieht wie folgt aus:Konnte keine Dateideklaration für die Variable

myThHelper :: FilePath -> Q Exp 
myThHelper path = 
    runIO (compileThatFile path) >>= liftData 

Dies ist eine vereinfachte Version des Codes, aber es vermittelt hoffentlich, was ich bin zu tun versuchen.

Notiere die liftData Funktion, es ist neu in template-haskell-2.11 und es verspricht „Lift“ in Ausdruck jede Instanz von Data. Sehr cool und es kompiliert.

Allerdings, wenn ich es verwenden, etwa so:

main :: IO() 
main = do 
    let compiled = $(myThHelper "/path/to/my/file/foo.txt") 
    … 

Ich erhalte die folgende Fehlermeldung von dem Compiler:

• Can't find interface-file declaration for variable Data.Text.Internal.pack 
    Probable cause: bug in .hi-boot file, or inconsistent .hi file 
    Use -ddump-if-trace to get an idea of which file caused the error 
• In the first argument of ‘PName’, namely 
    ‘Data.Text.Internal.pack ((:) 'f' ((:) 'o' ((:) 'o' [])))’ 
    In the first argument of ‘Template’, namely 
    ‘PName (Data.Text.Internal.pack ((:) 'f' ((:) 'o' ((:) 'o' []))))’ 
    In the expression: 

usw. Jede Idee, was los ist und wie sie beheben es?


ich über Experimente bestätigt, dass das Problem von selbst nur manifestiert, wenn Typ-Daten hat Text darin zu heben. Ich werde ein Problem eröffnen.


And here it is.

Antwort

2

Dies scheint zu sein, weil die Funktion dataToQa erwartet, dass toConstr zeigt (die "pack" für Text ist) im selben Modul wird der Datentyp definiert werden. So sucht liftDatapack in Data.Text.Internal aber pack ist eigentlich in Data.Text.

Eine einfache Möglichkeit, zu beheben ist es nur für Text Ihre eigene Liftfunktion schreiben:

{-# LANGUAGE TemplateHaskell #-} 

import qualified Data.Text as T 
import Language.Haskell.TH.Syntax 

liftText :: T.Text -> Q Exp 
liftText txt = AppE (VarE 'T.pack) <$> lift (T.unpack txt) 

myThHelper :: FilePath -> Q Exp 
myThHelper path = 
    runIO (compileThatFile path) >>= liftText 

Wenn der Text ist in der Struktur, die Sie tief wollen, verwenden Sie dataToExpQ verwenden können, die Sie lässt Überschreiben Sie die Lift-Funktion für typspezifische Fälle:

+0

Ich befürchte, dass "einfacher Weg" wird nicht für mich arbeiten, weil meine Daten 'Text' nicht auf der obersten Ebene, aber tief im Inneren hat. – Mark

+1

@Mark In diesem Fall können Sie ['dataToExQ'] (http://hackage.haskell.org/package/template-haskell-2.11.0.0/docs/Language-Haskell-TH-Syntax.html#v:dataToExpQ verwenden). Ich habe meine Antwort aktualisiert. – cchalmers

+0

Das ist jetzt interessant. Ich überprüfe es, sobald ich Zeit habe und akzeptiere deine Antwort, wenn es funktioniert. – Mark