Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load pure global variable from file

I have a file with some data in it. This data never changes and I want to make it available outside of the IO monad. How can I do that?

Example (note that this is just an example, my data is not computable):

primes.txt:

2 3 5 7 13

code.hs:

primes :: [Int]
primes = map read . words . unsafePerformIO . readFile $ "primes.txt"

Is this a "legal" use of unsafePerformIO? Are there alternatives?

like image 467
helami Avatar asked Oct 03 '12 20:10

helami


People also ask

How do you use global variables across files in Python?

To use global variables between files in Python, we can use the global keyword to define a global variable in a module file. Then we can import the module in another module and reference the global variable directly. We import the settings and subfile modules in main.py . Then we call settings.

How can use global variable in PHP from another file?

In case you need to access your variable $name within a function, you need to say "global $name;" at the beginning of that function. You need to repeat this for each function in the same file. In other words: write global $var before you use it in another function.

Can global variables be used in different files?

A global variable is accessible to all functions in every source file where it is declared. To avoid problems: Initialization — if a global variable is declared in more than one source file in a library, it should be initialized in only one place or you will get a compiler error.


1 Answers

You could use TemplateHaskell to read in the file at compile time. The data of the file would then be stored as an actual string in the program.

In one module (Text/Literal/TH.hs in this example), define this:

module Text.Literal.TH where

import Language.Haskell.TH
import Language.Haskell.TH.Quote

literally :: String -> Q Exp
literally = return . LitE . StringL

lit :: QuasiQuoter
lit = QuasiQuoter { quoteExp = literally }

litFile :: QuasiQuoter
litFile = quoteFile lit

In your module, you can then do:

{-# LANGUAGE QuasiQuotes #-}
module MyModule where

import Text.Literal.TH (litFile)

primes :: [Int]
primes = map read . words $ [litFile|primes.txt|]

When you compile your program, GHC will open the primes.txt file and insert its contents where the [litFile|primes.txt|] part is.

like image 112
dflemstr Avatar answered Sep 22 '22 18:09

dflemstr