Is it possible to read the derived instances in GHC? [duplicate] - haskell

So, in Haskell, it's really easy to do this:
data Foo = Bar | Baz
deriving (Read, Show)
This is great, but I'd like to be able to pass some data as a string from Haskell to the Elm language. The languages are similar enough that, if I had a Haskell implementation of Read, I could easily convert it to Elm by hand.
The problem is, when I use deriving, the function is automatically generated, but I can't actually see what it does.
I'm wondering, is there a way to automatically generate the code for parsing and showing using Read and Show, so that I could actually see the code itself?

You can use the the -ddump-deriv GHC option to see the code for derived instances:
ghc -ddump-deriv test.hs
[1 of 1] Compiling Test ( test.hs, test.o )
==================== Derived instances ====================
Derived instances:
instance GHC.Show.Show Test.FooBar where
GHC.Show.showsPrec _ Test.Foo = GHC.Show.showString "Foo"
GHC.Show.showsPrec _ Test.Bar = GHC.Show.showString "Bar"
GHC.Show.showList = GHC.Show.showList__ (GHC.Show.showsPrec 0)
Generic representation:
Generated datatypes for meta-information:
Representation types:

For stack:
stack build --ghc-options="-ddump-deriv"
Output in my specific case is: .stack-work/dist/x86_64-linux-nix/Cabal-2.4.0.1/build/app/app-tmp/src/

Related

What does the symbol `!` mean in type declarations in Haskell?

In my studies of Haskell, I see the symbol ! used in type declarations. See an example:
data Foo = MkFoo
{ _bar :: !Bar
, ...
}
My question is: why is it used and what is the difference to a declaration without it?
Fields marked with an exclamation point are made strict at the site of applications of the associated constructor. For example, your data declaration would be exactly the same as without the ! but writing the following kind of thing everywhere your code uses MkFoo:
bar `seq` MkFoo { _bar = bar }
Full details are in the Report.

cmdargs value arguments without equals sign

I use cmdargs to write CLI parsers for my Haskell programs.
Let's assume this program, derived directly from their example:
{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs.Implicit
data Sample = Sample {hello :: String} deriving (Show, Data, Typeable)
sample = Sample{hello = def &= help "World argument" &= opt "world"}
&= summary "Sample v1"
main = print =<< cmdArgs sample
If this program is called cmdtest.hs, I can execute
$ runghc cmdtest.hs --hello=world
Sample {hello = "world"}
However, if I leave off the equals sign (like in the -o option in gcc -o foo foobar.c), cmdargs tries to recognize world as a positional argument
$ runghc cmdtest.hs --hello world
Unhandled argument, none expected: world
Is there any option / annotation I can set to allow this syntax in cmdargs?
Update: Using the short option exposes the same problem:
$ runghc cmdtest.hs -h world
Unhandled argument, none expected: world
Update 2: The FlagInfo data in the cmdargs Explicit module seems to suggest it is somehow possible, at least if using Explicit instead of Implicit
Your problem is that you're using opt which makes the value of --hello optional. So --hello world is taken to mean --hello without a value, followed by world as a positional parameter. This is of course a design choice in cmdargs, but I think it's a reasonable one, and it matches the behaviour of most other programs. Take out the opt and see if it works the way you want.

Compile-time check if a name is defined

Is it possible to check if a function is defined, and use it as the Just value of a Maybe type if it is? And use Nothing if it's not defined, of course.
I'm writing a wrapper around atom for use with the TI MSP430 line. Part of what I'm doing is making a function that quickly compiles the code in the right format for MSP430 controllers - for example, compiling an atom to use in a timer interrupt requires a function definition like so:
#pragma vector=TIMERA0_VECTOR __interrupt
void timerAisr(void) {
...
}
At the moment, I have an object that holds references to the function the user would like to use for each different ISR. It looks a bit like this:
mspProgram = MSP430Compilation {
setupFn = Nothing,
setupFnName = "setup",
loopFn = Nothing,
loopFnName = "loop",
timerAISR = Nothing,
timerAISRName = "timerAISR",
And so on. Very configurable - you can choose the name of the function to output in C code, and the Atom to compile for that function. But I've decided I'd like to take more of a convention-over-configuration approach and basically assume some sensible function names. So instead of passing one of these configuration objects, I want the compilation code to check for definitions of sensibly-named functions.
For example, if the user defines an Atom called timerAISR, then my code should compile that atom to a C function named the same, with the appropriate #pragma matter for it to service the timer A interrupt.
So what I need to do is sort of meta-Haskell, checking if the user has defined a function and using that in my library code. I imagine this might involve template Haskell, so I'm off to research it.
EDIT:
I've realised that my original solution was too simplistic once I tried to fit it into my actual code. I hadn't absorbed Haskell's namespacing, so I didn't realise that lookupValueName would not work on values defined in user code. Here's the situation I'm dealing with:
main.hs:
module Main where
import Library
a = 1
main = libraryMain
Library.hs:
{-# LANGUAGE TemplateHaskell #-}
module Library where
import Template
libraryMain :: IO ()
libraryMain = do
$(printSomethingIfIsDefined "a")
$(printSomethingIfIsDefined "b")
Template.hs:
{-# LANGUAGE TemplateHaskell #-}
module Template where
import Language.Haskell.TH
printSomethingIfIsDefined name = do
maybeFn <- lookupValueName name
case maybeFn of
Just fn -> [| putStrLn "It's defined!" |]
Nothing -> [| return () |]
This prints nothing. If I define a in Library.hs, it will print out once, because a is defined in that scope.

How to store recursive datatype with Data.Binary

Data.Binary is great. There is just one question I have. Let's imagine I've got a datatype like this:
import Data.Binary
data Ref = Ref {
refName :: String,
refRefs :: [(String, Ref)]
}
instance Binary Ref where
put a = put (refName a) >> put (refRefs a)
get = liftM2 Ref get get
It's easily to see that this is a recursive datatype, which works because Haskell is lazy. Since Haskell as a language uses neither references nor pointers, but presents the data as-is, I am not sure how this is going to be saved. I have the strong indication that this naive reproach will lead to an infinite bytestring...
So how can this type be safely saved?
If your data has no cycles you'll be fine. But a cycle, like
r = Ref "a" [("b", r)]
is indeed going to generate an infinite result. The only way around this is for you to give unique labels to all nodes and use those to avoid cycles when converting to binary.

Idiomatic way to modify a member variable

I know Haskell isn't OO so it isn't strictly a 'member variable'.
data Foo = Foo {
bar :: Int,
moo :: Int,
meh :: Int,
yup :: Int
}
modifyBar (Foo b m me y) = (Foo b' m me y)
where b' = 2
This is how my code looks at the moment. The problem is I am now making data types with 16 or more members. When I need to modify a single member it results in very verbose code. Is there a way around this?
modifyBar foo = foo { bar = 2 }
This syntax will copy foo, and then modify the bar field of that copy to 2. This could be naturally extended to more fields, so you don't need to write that modifyBar function at all.
(See http://book.realworldhaskell.org/read/code-case-study-parsing-a-binary-data-format.html#id625467)
Haskell's "record syntax" that #KennyTM shows is the built-in way to do this, though keep in mind that it's still just a way of constructing a new value based on the old one.
There are some annoying limitations to record syntax, though, particularly that the form used to "modify" a single item in a record aren't first-class entities in the language, so you can't abstract over them and pass them around the way you'd do with a regular function.
An alternative is using a library such as fclabels which provides similar functionality, using Template Haskell to auto-generate accessor functions instead of built-in syntax. The result is often much nicer, with the downside that you now have a dependency on TH....

Resources