The :browse, :info and :type GHCi commands are very convenient.
Is it possible to get the same information programmaticaly in a Haskell program? That is, to get the exported functions from a module, the types of stuff, etc.
:browse - when a Haskell program is compiled, no (useful) information is kept about which module something came from, so your program wouldn't be able to access that information.
:type - Unless you're using Data.Typeable, types aren't visible at all at runtime. Types in Haskell are mostly for the compiler to check to correctness/safety of code.
:info - See above.
for getting functions of a module at compile time - the language-haskell-extract package could be interesting to you. It helps you extracting functions according to a regular expression.
http://hackage.haskell.org/package/language-haskell-extract-0.2.1
Daniel Fischer commented:
You can use the GHC API. I'm not aware of a simpler way.
Seems to be fiddly but to work fine. And I guess this is how :info works in GHCi. Thanks for the suggestion.
Related
I am a data scientist familiar with languages such as R and python.
I have been trying to learn haskell for two months.
There is a module people employ to deal with frames in haskell similarly to common packages in those other languages (tidyverse in R and pandas in python).
The problem is: the common function for extracting data type for a csv is simply returning a message error:
tableTypes "base" "base.csv"
<interactive>:2:1: error:
• No instance for (Show Language.Haskell.TH.Lib.DecsQ)
arising from a use of ‘print’
• In a stmt of an interactive GHCi command: print it
I cannot understand what this message means and I could not find any answer on Google. Could someone help me solve it?
Link to the module: http://hackage.haskell.org/package/Frames
You've stumbled into a case that's involves some advanced features of Haskell. The problem is that tableTypes "base" "base.csv" is a template haskell splice. For some reason, a few years back ghc was modified to allow bare expressions at the top level as splices, instead of requiring the standard splice syntax of $(expression generating code to splice).
But the bare expression syntax is incompatible with ghci. If you enter a bare expression in ghci, it tries to evaluate and print it (with some special rules for expressions that result in IO values).
When ghci evaluates tableTypes "base" "base.csv" it gets a result back that's not an instance of Show, because the template haskell Q environment is not printable. It contains a bunch of functions.
You have a few options here, depending on what you actually are trying to do. You could use runQ in ghci to dump the AST generated by the splice. That's probably not what you want. That's more likely to be a tool that's useful when you're developing a splice than for testing a library that uses them.
You could enable the TemplateHaskell extension within ghci and actually have it perform the splice interactively, but that's somewhat fiddly to get to work and you don't end up seeing much anyway.
I think the most practical solution is to move your code into a file. You can load said file from ghci if you desire - the important part is that in the context of a file, there's no longer any syntactic ambiguity - that's definitely a splice to evaluate while compiling, not an expression to evaluate interactively.
When I compile a Haskell file with ghci, typically with :load, and if there is no type error, all the expressions are loaded in the ghc interpreter. It's very nice: I can play around with :t to figure out the type of various expressions.
My problem is: if there is a tiny error somewhere, ghci is not able to load anything (not even the imported modules!!), which makes finding the right types even more difficult. I always do the same: comment out all the bits that do not typecheck, find the relevant types wiht :t in ghci, and de-comment.
But this is so tedious! Is there a better workflow for "partially compiling" a Haskell source code?
As #MikhailGlushenkov pointed out in the comments, the solution is to use the -fdefer-type-errors flag to GHCi.
I'm trying to understand Philip Wadler's "Essence of Functional Programming", and I seem to be held back by his assertion that "No knowledge of Haskell is necessary to understand this paper." Maybe not, but his examples sure require some.
Specifically, I'm trying to understand his example interpreter. When I try to compile this using GHC, or load it using :load, it complains not in scope: showint. Perhaps you meant showInt. When I replace the token with showInt, it says Not in scope: showInt.
I'd really like to believe Dr. Wadler when he says all I need to know is contained in his paper.
I'd really like to get it working under GHCI, so I can try various expressions under the interpreter. I'm new to Haskell, and was duly warned about the opaqueness of its error messages, but this seems designed to perplex!
The showInt function is part of the Numeric module, so you have to import Numeric to have it in scope. I guess the typo hint system knows about modules you haven't imported.
showInt also doesn't return a string directly but instead a String -> String function. I think this functionality is used for showing things composed of multiple parts more efficiently, but here it'd just be a pain and your code won't typecheck as is.
Instead, you can replace showint with just show and let the compiler figure it out. show is Haskell's toString and is overloaded for any type it's reasonable to convert to a string.
I have some Haskell code, and would like a Fay script to be able to access it. The problem is the Haskell code uses monads. Fay doesn't support arbitrary monads. How do I get my Haskell code to work with Fay? Namely, the Fay script needs to be able to access functions from the Haskell script. What do I do?
I may not quite understand what you are asking.
You have some Haskell that isn't valid Fay, so if you want to run it as Fay code you would need to replace unsupported features, for example by using monomorphic functions to replace the missing Monad instances (note that you can use RebindableSyntax here)
If you compile the Haskell code with GHC there is no reasonable way to interface with the functions from Fay. You would need to invoke an external process from Fay inside node.js or similar.
I'm just starting to learn Haskell and would find it very helpful to see how Haskell functions are implemented. I've been able to find the Standard Prelude on different question, but I'm now interested in Data.List. Is there any way to find the source for these functions?
I would really like to see permutations and nub (and the rest, but these are the most interesting for me right now).
Here you go: http://hackage.haskell.org/packages/archive/base/latest/doc/html/src/Data-List.html
More generally, if you look at the documentation page for Data.List you'll see "Source" links to the right of the type signatures, which will take you directly to the source for that function.
You can find the source for the rest of the standard libraries the same way and, in fact, for nearly everything on Hackage.
The documentation of the Data.List module is found here:
http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-List.html
And the source here:
http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/Data-List.html
In GHCI, you can do :browse Data.List to find more about this module. Note that the basic list definitions and operations are also found in base packages e.g. GHC.Base, GHC.List.
Other links shared did not work for me, check this out
http://hackage.haskell.org/package/base-4.12.0.0/docs/src/Data.List.html
"Source" link is to the top right of the page.
To view any function implementation click on it.