2

Is there a way to initialize a function

someText :: Text

which value will be stored in a file available at compile time?

I thought I could use TH for that, but for now I just found

embedFile :: FilePath -> Q Exp
runQ :: Quasi m => Q a -> m a

I can only unwrap Q into IO:

instance Quasi IO    
instance Quasi Q

I guess I need Identity instance of Quasi, but there is no one.

2 Answers2

8

Isn't this just

someText :: Text
someText = $(embedStringFile "path/to/file")

Am I missing something?

(It's the TH splice itself that turns Q Exp into some other type at run-time. You shouldn't need any typeclass instances or anything...)

MathematicalOrchid
  • 61,854
  • 19
  • 123
  • 220
2
# foo.txt
barbazblub
module FileText where
import Language.Haskell.TH

fileText :: FilePath -> Q Exp
fileText fp = LitE . StringL <$> runIO (readFile fp)
{-# LANGUAGE TemplateHaskell #-}
module Foo where

import FileText

main = putStrLn $(fileText "foo.txt")
$ runhaskell Foo.hs 
barbazblub
leftaroundabout
  • 117,950
  • 5
  • 174
  • 319
  • Thanks! I like both answers, but I'll accept yours because it's more detailed. –  Jun 05 '17 at 13:39
  • @wowofbob thanks, but MathematicalOrchid's suggestion is better – `embedStringFile`, which I wasn't aware of, is the standard version of `fileText` and therefore preferrable. – leftaroundabout Jun 05 '17 at 22:54