Is there a way to lift Template Haskell Names? - haskell

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.

Related

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.

How can I automate testing a Template Haskell function?

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.

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.

How to get the literal value of a TemplateHaskell named variable

If I have a Name in TemplateHaskell and want to find out the value of the variable that it names, provided that the variable is declared as a literal, can this be done?
var = "foo"
-- Can `contentsOf` be defined?
$((contentsOf . mkName $ "var") >>= guard . (== "foo"))
In theory, yes. In practice, no.
Finding out stuff about existing names is done using reify :: Name -> Q Info, and for a definition like that you would get back a VarI value, which includes a Maybe Dec field. This would seem to suggest that you might in some cases be able to get the syntax tree for the declaration of the variable, which would allow you to extract the literal, however current versions of GHC always returns Nothing in this field, so you're out of luck for a pure TH solution.
However, TH does allow arbitrary IO actions to be run, so you could potentially work around this by loading and parsing the module yourself using something like haskell-src-exts, however I suspect that would be more trouble than it's worth.

FastCGI Haskell script to make use of Pandoc text conversion

1. Motivation
I'm writing my own mini-wiki. I want to be able to easily convert from markdown to LATEX/HTML and vice versa. After some searching I discovered Pandoc, which is written in Haskell and that I could use the FastCGI module to run a Haskell program on my Apache server.
2. Problem/ Question
I'm not sure how to what protocol I should use to send my FastCGI script the input/output variables (POST/GET?) and how this is done exactly. Any ideas, suggestions, solutions?
3. Steps taken
3.1 Attempt
Here is what I've done so far (based on example code). Note, I have no experience in Haskell and at the moment I don't have too much time to learn the language. I'd just love to be able to use the pandoc text format conversion tool.
module Main ( main ) where
import Control.Concurrent
import Network.FastCGI
import Text.Pandoc
--initialize Variables/ functions
fastcgiResult :: CGI CGIResult
markdownToHTML:: String -> String
--implement conversion function
markdownToHTML s = writeLaTeX defaultWriterOptions {writerReferenceLinks = True} (readMarkdown defaultParserState s)
--main action
fastcgiResult = do
setHeader "Content-type" "text/plain"
n <- queryString
output $ (markdownToHTML n)
main :: IO ()
main = runFastCGIConcurrent' forkIO 10 fastcgiResult
This code reads the string after the question mark in the request url. But this is not a good solution as certain characters are omitted (e.g. '#' ) and spaces are replaced by "/20%".
Thanks in advance.
3.2 Network.CGI
Documentation found here. Under the heading "Input" there are a number of methods to get input. Which one is right for me?
Is it :
Get the value of an input variable, for example from a form. If the variable has multiple values, the first one is returned. Example:
query <- getInput "query"
So lets say I have a HTML POST form with name='Joe' can I grab this using getInput? And if so how do I handle the Maybe String type?
The fastCGI package is actually a extension of the cgi package, which includes the protocol types for receiving request data and returning result pages. I'd suggest using CGI to start with, and then move to fastCGI once you know what you are doing.
You might also want to look at this tutorial.
Edit to answer questions about the tutorial:
"Maybe a" is a type that can either contain "Just a" or "Nothing". Most languages use a null pointer to indicate that there is no data, but Haskell doesn't have null pointers. So we have an explicit "Maybe" type instead for cases when the data might be null. The two constructors ("Just" and "Nothing") along with the type force you to explicitly allow for the null case when it might happen, but also let you ignore it when it can't happen.
The "maybe" function is the universal extractor for Maybe types. The signature is:
maybe :: b -> (a -> b) -> Maybe a -> b
Taking the arguments from front to back, the "Maybe a" third argument is the value you are trying to work with. The second argument is a function called if the third argument is "Just v", in which case the result is "f v". The first argument is the default, returned if the third is "Nothing".
In this case, the trick is that the "cgiMain" function is called twice. If it finds an input field "name" then the "mn" variable will be set to (Just "Joe Bloggs"), otherwise it will be set to (Nothing). (I'm using brackets to delimit values now because quotes are being used for strings).
So the "maybe" call returns the page to render. The first time through no name is provided, so "mn" is (Nothing) and the default "inputForm" page is returned for rendering. When the user clicks Submit the same URL is requested, but this time with the "name" field set, so now you get the "greet" function called with the name as an argument, so it says "Hello Joe Bloggs".

Resources