How can I automate testing a Template Haskell function? - haskell

I defined a function using Template Haskell which generates a function definition given some type. The type is basically
makeFunc :: Name -> Q [Dec]
Right now, I use the -ddump-splices switch with GHC to see the generated splices. How can I automate this to verify that different types yield the expected splices?
A basic approach might be to just redirect the generated splice to a file and then compare that, but the generated code may well be different since it involves various identifiers constructed via newName.

Related

How can I write property tests for Template Haskell splices?

I always like to be able to write property tests for my code. When that code is Template Haskell, I'm mostly interested in the behavior of the generated code. Intuitively, I'd like to be able to write things like
import Test.QuickCheck
checkLift :: (Eq a, Lift a, Show a) => a -> Property
checkLift a = $$(liftTyped a) === a
prop_myLiftWorks :: MyType -> Property
prop_myLiftWorks = checkLift
Unfortunately, the Template Haskell stage restriction makes this exact approach totally impossible. The generated splices have to be compiled separately to run. Is there some easy way to spin up a GHC instance in the test suite (or do something with the ghc package or haskell-language-server?) and throw splices at it?
Ideally, I'd want to be able to work with declaration splices as well as expression splices. For example, to write property tests for deriving-compat, I'd want to generate arbitrary datatype declarations of various sorts and then compare Template Haskell-derived instances to GHC-derived ones.

Require that a specific Haskell type defined in code is invalid

Is it possible to instruct GHC compiler to require that a specific value in code has invalid type, without ever using this value?
A contrived example is:
data Box a = Num a => Box a
goodBoxSample :: Box Int
goodBoxSample = Box 1
-- below definition and binding are expected to fail compilation
badBoxSample :: Box String
badBoxSample = Box "foo"
Is there a way to inform the compiler that badBoxSample is expected to fail (e.g. with some pragma, rather than commenting it out as a known bad sample), so that the code compiles only if badBoxSample fails to type-check?
The motivation here is the same as for writing a test (in some other language) with the code that is required to throw exception for the test case to pass.
Not possible. You're basically asking for a way to prove that there's no instance Num String, but Haskell operates under the open-world assumption, which means that someone could always declare such an instance.
Somebody posted a very helpful answer here, but before I managed to accept it was removed... Thank you anyway, and here it is for the reference:
https://hackage.haskell.org/package/generic-lens-2.0.0.0/docs/Data-Generics-Product-Fields.html
In short, the goal of testing failing types can be achieved with doctest, in the way the linked library does it.

Is there a way to lift Template Haskell Names?

Since Name has a Show instance and strings can be used to generate a corresponding Name, I thought about using the following method:
\ name -> [e| mkName $(lift (show name)) |]
This works fine in ghci. But in compiled code, the actual compiled variables look like p_a4hEk, whereas the strings produced by Show look like p_6989586621680030942.
What is happening here? Is there a way to lift a Name into a Template Haskell ExpQ?
Use case: I am writing a TH API that can build complex and efficient Haskell functions based on human-readable user descriptions. I am attaching to the returned function a documentation that explains the purpose and type of each parameter in human readable terms. It would be nice if the documentation could also contain the Name used for that parameter in the code, so that the user can review the spliced code as needed and recognize which parameter is which.

Best way to bring the contents of a textfile into a reflex project

I have a 70 line text file, whose contents I want to have as the initial value of a text area within my project. What is the best way to do this? Normally I would use readFile but I can't seem to use it in this context.
You can use Template Haskell to load the file at compile time and store its contents in a toplevel definition. The file-embed package on Hackage implements this functionality for you:
This module uses Template Haskell. Following is a simplified
explanation of usage for those unfamiliar with calling Template
Haskell functions.
The function embedFile in this modules embeds a file into the
executable that you can use it at runtime. A file is represented as a
ByteString. However, as you can see below, the type signature
indicates a value of type Q Exp will be returned. In order to
convert this into a ByteString, you must use Template Haskell
syntax, e.g.:
$(embedFile "myfile.txt")
This expression will have type ByteString.

HASKELL - Change Type

I need to create a function f:: Log->[String] that does that (((o, i ,d),s) = [(o, i ,d)]
type Log = (Plate, [String])
type Plate = (Pin, Pin, Pin)
type Pin = (Char, Int)
If you're on a page like this, click "Source" on the fir right side, next to the function that you're interested in.
If you need to look up a function, Hayoo! and Hoogle will link you to documentation pages like the one above.
An important thing to note, though is that show doesn't have one definition. show is a function defined for all data types in the Show (with a capital "S") typeclass. So for example, here is the full source for the Show typeclass. Show is defined within the typeclass as just show :: a -> String. But if you search for "instance Show Bool" or "instance Show Int", you'll find specific definitions.
For the second part of your question, the easiest way to get a show function for a new type is to simply write deriving (Show) below it. For example,
data Foo = Foo Int Int
deriving (Show)
Now I can use show on data with type Foo.
g :: Log -> [String]
g (plate, _) = [show plate]
Use hoogle to find this sort of information.
Example: http://www.haskell.org/hoogle/?hoogle=show
Once you've found the function you'd like in the list, click and there you'll find a Source link on the right hand side of the page.
NB this is an answer to the original question:
Where can I see the codes of the predefined functions in haskell ?? Mainly the function SHOW?
It's true that you can use Hoogle to search for functions defined in the Prelude (and other modules), but the source code itself is located at Hackage.
Hackage is a database of Haskell packages. You can download new packages from it, and also view the Haddock documentation for every package in the database.
This is the Haddock page for the standard Prelude. It documents the type classes, data types, types, and top-level functions exported by the Prelude module. To the right of each definition header is a link that says "Source". You can click this to be taken to an online copy of the source code for the module you're viewing.
On preview, you're now asking a different question entirely, and on preview again in fact the original question has been edited out of this post.
Your new question is unclear, but this solution will work to produce the output in your example.
> [fst ((('O',0),('I',0),('D',1)),"O->D")]
[(('O',0),('I',0),('D',1))]
I think you're using list notation instead of double quotes to identify Strings, by the way, so I fixed that around 0->D above. So you might also try this instead.
> show (fst ((('O',0),('I',0),('D',1)),"O->D"))
"(('O',0),('I',0),('D',1))"
This works because you have only defined type synonyms (by using type in your declarations instead of data) on data structures which already have Show instances.

Resources