Cabal rebuild on embedded file change - haskell

I'm using the file-embed package thusly:
import qualified Data.ByteString as B
import qualified Data.ByteString.Internal as B (w2c)
import qualified Data.FileEmbed as E
initWindow = do
b <- Gtk.builderNew
let glade = map B.w2c $ B.unpack $ $(E.embedFile "window.glade") in
Gtk.builderAddFromString b glade
...
Is it possible to make cabal rebuild this file even when only the glade file changes?

Support for this will be/has been added in GHC 7.4/7.6. The problem is that the compiler doesn't allow TemplateHaskell splices to add file dependencies yet. See this ticket for more information.
When this change lands, you can use the following code to create a new embedFile' function:
import Data.FileEmbed
import Language.Haskell.TH.Syntax
import Language.Haskell.TH.Lib
embedFile' :: FilePath -> Q Exp
embedFile' path = do
qAddDependentFile path
embedFile path
This has to be in a separate module from where you use the TH function.

Related

In Haskell, is it possible to qualify part of an imported module?

I'd like to be able to do something like: import qualified Data.Massiv.Array (qualified map).
This gives error: parse error on input `map'.
Or better yet, import qualified Data.Massiv.Array (qualified map) as AM, so I also can access foo as either foo or AM.foo, unless foo == map, then I have to use AM.map. This is to avoid conflict with Prelude.map.
Write two imports and you can use map as AM.map and use other functions without AM..
import qualified Data.Massiv.Array as AM
import Data.Massiv.Array hiding (map)

How does "import Database.Persist as X hiding (get)" from the yesod-sqlite template works

I am using the yesod-sqlite template and trying to use the get function from Database.Persist in a test.
Here is my code:
[Entity _ task] <- runDB $ selectList [TaskName ==. name] []
...
user <- runDB $ X.get (taskUserId task)
And the error I am getting:
my_project/test/Handler/TaskSpec.hs:47:29: error:
Not in scope: ‘X.get’
No module named ‘X’ is imported.
In the TestImport.hs file, I saw this line:
import Database.Persist as X hiding (get)
To my understanding it should be hidding the get function from the HSpec module, so I could use X.get for database retrieving. I also tried with Database.Persist.get and just get with the same result.
So my doubt is: what that line in TestImport.hs is doing?
The import line is importing everything in the Database.Persist module except get, optionally qualified.
If I'm understanding correctly and you want to import only get qualified, and everything else unqualified, you could use:
import Database.Persist hiding (get)
import qualified Database.Persist as X (get)

Haskell Diagrams Output without commandline

I have one question: I know how to output svg file with a help of ghc --make Strukturine.hs command in Terminal. As I understood it uses import Diagrams.Backend.SVG.CmdLine . Is it possible somehow load Strukturine.hs file with the help of :load Strukturine.hs in terminal and then just put the name of function for example: strukturine. That function should output a scheme/picture (to svg file).
The beginning of Strukturine.hs file looks like this
{-# LANGUAGE NoMonomorphismRestriction #-}
module Strukturine where
import Diagrams.Prelude
import Diagrams.Backend.SVG.CmdLine
import Data.Maybe (fromMaybe)
import Data.Char
import Input
import qualified Input(getNumber) --other module
main = mainWith(strukturine :: Diagram B R2)
You can use the function renderSVG from Diagrams.Backend.SVG.
renderSVG :: FilePath -> SizeSpec2D -> Diagram SVG R2 -> IO ()
For example to render a 400x400 svg:
import Diagrams.Backend.SVG (renderSVG)
outputFile :: FilePath
outputFile = "strukturine.svg"
dimensions :: SizeSpec2D
dimensions = mkSizeSpec (Just 400) (Just 400)
strukturineDiagram :: Diagram SVG R2
strukturine = do renderSVG outputFile dimensions strukturineDiagram
See http://projects.haskell.org/diagrams/haddock/Diagrams-Backend-SVG.html#v:renderSVG
And for more specific rendering, see: http://projects.haskell.org/diagrams/doc/cmdline.html

Data.Text.Lazy.Internal.Text to Data.Text.Text

How can I convert the internal value to a Data.Text.Text?
import qualified Data.Text as T
import qualified Data.Text.Lazy.IO as X
main = do
name <- X.readFile "someFile"
How can I convert the value in name to T.Text?
There's a function explicitly for that, Data.Text.Lazy.toStrict.
I suppose you're actually doing something else in between that requires reading as a lazy Text, otherwise, you should read as a strict Text directly of course.

How to import a .hs file in Haskell

I have made a file called time.hs. It contains a single function that measures the execution time another function.
Is there a way to import the time.hs file into another Haskell script?
I want something like:
module Main where
import C:\Haskell\time.hs
main = do
putStrLn "Starting..."
time $ print answer
putStrLn "Done."
Where time is defined in the 'time.hs' as:
module time where
Import <necessary modules>
time a = do
start <- getCPUTime
v <- a
end <- getCPUTime
let diff = (fromIntegral (end - start)) / (10^12)
printf "Computation time: %0.3f sec\n" (diff :: Double)
return v
I don't know how to import or load a separate .hs file. Do I need to compile the time.hs file into a module before importing?
Time.hs:
module Time where
...
script.hs:
import Time
...
Command line:
ghc --make script.hs
If the module Time.hs is located in the same directory as your "main" module, you can simply type:
import Time
It is possible to use a hierarchical structure, so that you can write import Utils.Time.
As far as I know, the way you want to do it won't work.
For more information on modules, see here Learn You a Haskell, Making Our Own Modules.
Say I have two files in the same directory: ModuleA.hs and ModuleB.hs.
ModuleA.hs:
module ModuleA where
...
ModuleB.hs:
module ModuleB where
import ModuleA
...
I can do this:
ghc -I. --make ModuleB.hs
Note: The module name and the file name must be the same. Otherwise it can't compile. Something like
Could not find module '...'
will occur.

Resources