Data constructor in template haskell - haskell

I'm trying to create the ring Z/n (like normal arithmetic, but modulo some integer). An example instance is Z4:
instance Additive.C Z4 where
zero = Z4 0
(Z4 x) + (Z4 y) = Z4 $ (x + y) `mod` 4
And so on for the ring. I'd like to be able to quickly generate these things, and I think the way to do it is with template haskell. Ideally I'd like to just go $(makeZ 4) and have it spit out the code for Z4 like I defined above.
I'm having a lot of trouble with this though. When I do genData n = [d| data $n = $n Integer] I get "parse error in data/newtype declaration". It does work if I don't use variables though: [d| data Z5 = Z5 Integer |], which must mean that I'm doing something weird with the variables. I'm not sure what though; I tried constructing them via newName and that didn't seem to work either.
Can anyone help me with what's going on here?

The Template Haskell documentation lists the things you are allowed to splice.
A splice can occur in place of
an expression; the spliced expression must have type Q Exp
an type; the spliced expression must have type Q Typ
a list of top-level declarations; the spliced expression must have type Q [Dec]
In both occurrences of $n, however, you're trying to splice a name.
This means you can't do this using quotations and splices. You'll have to build declaration using the various combinators available in the Language.Haskell.TH module.
I think this should be equivalent to what you're trying to do.
genData :: Name -> Q [Dec]
genData n = fmap (:[]) $ dataD (cxt []) n []
[normalC n [strictType notStrict [t| Integer |]]] []
Yep, it's a bit ugly, but there you go. To use this, call it with a fresh name, e.g.
$(genData (mkName "Z5"))

Related

Typed Tagless Final Interpreters: what is the use of duplicate?

This question is related to the paper Typed Tagless Final Interpreters. In page 11, a function trice is presented, which relies on a duplicate function:
I've tried coding this into Haskell, and the resulting functions look as follows:
thrice :: (Int, (String, Tree)) -> IO () -- Is this the most generic type we can give?
thrice x0 = do
x1 <- dupConsume eval x0
x2 <- dupConsume view x1
print $ toTree x2
where
dupConsume ev y = do
print (ev y0)
return y1
where
(y0, y1) = duplicate y
However, since I cannot seem to be able to give a more generic type to thrice I could have just written the simpler function:
thrice' :: (Int, (String, Tree)) -> IO ()
thrice' (reprInt, (reprStr, reprTree)) = do
print $ eval reprInt
print $ view reprStr
print $ toTree reprTree
So I was wondering what is the use of duplicate in this example?
First, as an aside, note that the code in that article is already valid Haskell code, except that some symbols are used in place of usual Haskell syntax. For example, the symbol "◦" is used in place of the (.) operator for function composition.
So you can write thrice as the following valid Haskell code, straight from its definition in the article:
thrice x = dup_consume eval x >>= dup_consume view
>>= print . toTree
dup_consume ev x = print (ev x1) >> return x2
where (x1, x2) = duplicate x
Anyway, back to your question... As you have rightly pointed out, the interpreter duplicate has no real purpose. For example, you can define dup_consume as either the version above or else drop the duplicate entirely and write:
dup_consume ev x = print (ev x1) >> return x2
where (x1, x2) = x
And, of course, you can merge the definition of dup_consume directly into thrice, as you've done.
However, all the final "interpreters" in the article have no real purpose. That's kind of the point. In particular, you don't need eval or view to define thrice either. The following works fine, too:
thrice' :: (Int, (String, Tree)) -> IO ()
thrice' (reprInt, (reprStr, reprTree)) = do
print $ reprInt
print $ reprStr
print $ reprTree
after which you can do the following:
> thrice' (add (lit 5) (neg (lit 2)))
3
"(5 + (-2))"
Node "Add" [Node "Lit" [Leaf "5"],Node "Neg" [Node "Lit" [Leaf "2"]]]
>
The idea with these final interpreters is that the typing determines the interpretation. The purpose of the interpreters is only to add typing information without explicit type signatures. So, eval (neg (lit 1)) can be entered at the GHCi prompt without a type signature:
> eval (neg (lit 1))
-1
>
and it "works" because eval -- which is just the id function -- forces the return value to be an integer, which in turn selects the correct instance to evaluate the final expression rather than viewing it or something else. But you could also write:
> neg (lit 1) :: Int
-1
>
to get the same effect.
It turns out that duplicate is even less necessary than the other interpreters, because in the only place where it's used -- namely the definition of dup_consume:
dup_consume ev x = print (ev x1) >> return x2
where (x1, x2) = duplicate x
the type checker can already infer that a tuple is needed, so any final expression provided for x, like neg (lit 1) will necessarily be interpreted as the duplicating instance for tuples (i.e,. the instance defined right before the definition of duplicate), so -- as noted above -- you could just write:
dup_consume ev x = print (ev x1) >> return x2
where (x1, x2) = x
and the type checker would figure it out.
I might be wrong, but I suspect your thrice' function may involve parsing the expression multiple times, whereas Oleg's duplicate trick will only copy the parse tree (i.e. parse result).
The need for duplication arises from the pattern matching on parse result, which assigns a monomorphic type to the matched parse result. Therefore, once you've chosen an interpreter for it, you're stuck with it. The paper mentions a higher-rank encoding to reclaim this lost polymorphism at the expense of extensibility, which defeats the point of tagless final interpreters.
An alternative is the duplicate trick which copies the (monomorphic) parse result into another (monomorphic) value to be interpreted differently.
Of course, if parsing always succeeds (for instance by encoding parse errors directly in your parse tree) then there's no need for duplicate since the parse result can remain polymorphic and be interpreted differently.

Haskell's (<-) in Terms of the Natural Transformations of Monad

So I'm playing around with the hasbolt module in GHCi and I had a curiosity about some desugaring. I've been connecting to a Neo4j database by creating a pipe as follows
ghci> pipe <- connect $ def {credentials}
and that works just fine. However, I'm wondering what the type of the (<-) operator is (GHCi won't tell me). Most desugaring explanations describe that
do x <- a
return x
desugars to
a >>= (\x -> return x)
but what about just the line x <- a?
It doesn't help me to add in the return because I want pipe :: Pipe not pipe :: Control.Monad.IO.Class.MonadIO m => m Pipe, but (>>=) :: Monad m => m a -> (a -> m b) -> m b so trying to desugar using bind and return/pure doesn't work without it.
Ideally it seems like it'd be best to just make a Comonad instance to enable using extract :: Monad m => m a -> a as pipe = extract $ connect $ def {creds} but it bugs me that I don't understand (<-).
Another oddity is that, treating (<-) as haskell function, it's first argument is an out-of-scope variable, but that wouldn't mean that
(<-) :: a -> m b -> b
because not just anything can be used as a free variable. For instance, you couldn't bind the pipe to a Num type or a Bool. The variable has to be a "String"ish thing, except it never is actually a String; and you definitely can't try actually binding to a String. So it seems as if it isn't a haskell function in the usual sense (unless there is a class of functions that take values from the free variable namespace... unlikely). So what is (<-) exactly? Can it be replaced entirely by using extract? Is that the best way to desugar/circumvent it?
I'm wondering what the type of the (<-) operator is ...
<- doesn't have a type, it's part of the syntax of do notation, which as you know is converted to sequences of >>= and return during a process called desugaring.
but what about just the line x <- a ...?
That's a syntax error in normal haskell code and the compiler would complain. The reason the line:
ghci> pipe <- connect $ def {credentials}
works in ghci is that the repl is a sort of do block; you can think of each entry as a line in your main function (it's a bit more hairy than that, but that's a good approximation). That's why you need (until recently) to say let foo = bar in ghci to declare a binding as well.
Ideally it seems like it'd be best to just make a Comonad instance to enable using extract :: Monad m => m a -> a as pipe = extract $ connect $ def {creds} but it bugs me that I don't understand (<-).
Comonad has nothing to do with Monads. In fact, most Monads don't have any valid Comonad instance. Consider the [] Monad:
instance Monad [a] where
return x = [x]
xs >>= f = concat (map f xs)
If we try to write a Comonad instance, we can't define extract :: m a -> a
instance Comonad [a] where
extract (x:_) = x
extract [] = ???
This tells us something interesting about Monads, namely that we can't write a general function with the type Monad m => m a -> a. In other words, we can't "extract" a value from a Monad without additional knowledge about it.
So how does the do-notation syntax do {x <- [1,2,3]; return [x,x]} work?
Since <- is actually just syntax sugar, just like how [1,2,3] actually means 1 : 2 : 3 : [], the above expression actually means [1,2,3] >>= (\x -> return [x,x]), which in turn evaluates to concat (map (\x -> [[x,x]]) [1,2,3])), which comes out to [1,1,2,2,3,3].
Notice how the arrow transformed into a >>= and a lambda. This uses only built-in (in the typeclass) Monad functions, so it works for any Monad in general.
We can pretend to extract a value by using (>>=) :: Monad m => m a -> (a -> m b) -> m b and working with the "extracted" a inside the function we provide, like in the lambda in the list example above. However, it is impossible to actually get a value out of a Monad in a generic way, which is why the return type of >>= is m b (in the Monad)
So what is (<-) exactly? Can it be replaced entirely by using extract? Is that the best way to desugar/circumvent it?
Note that the do-block <- and extract mean very different things even for types that have both Monad and Comonad instances. For instance, consider non-empty lists. They have instances of both Monad (which is very much like the usual one for lists) and Comonad (with extend/=>> applying a function to all suffixes of the list). If we write a do-block such as...
import qualified Data.List.NonEmpty as N
import Data.List.NonEmpty (NonEmpty(..))
import Data.Function ((&))
alternating :: NonEmpty Integer
alternating = do
x <- N.fromList [1..6]
-x :| [x]
... the x in x <- N.fromList [1..6] stands for the elements of the non-empty list; however, this x must be used to build a new list (or, more generally, to set up a new monadic computation). That, as others have explained, reflects how do-notation is desugared. It becomes easier to see if we make the desugared code look like the original one:
alternating :: NonEmpty Integer
alternating =
N.fromList [1..6] >>= \x ->
-x :| [x]
GHCi> alternating
-1 :| [1,-2,2,-3,3,-4,4,-5,5,-6,6]
The lines below x <- N.fromList [1..6] in the do-block amount to the body of a lambda. x <- in isolation is therefore akin to a lambda without body, which is not a meaningful thing.
Another important thing to note is that x in the do-block above does not correspond to any one single Integer, but rather to all Integers in the list. That already gives away that <- does not correspond to an extraction function. (With other monads, the x might even correspond to no values at all, as in x <- Nothing or x <- []. See also Lazersmoke's answer.)
On the other hand, extract does extract a single value, with no ifs or buts...
GHCi> extract (N.fromList [1..6])
1
... however, it is really a single value: the tail of the list is discarded. If we want to use the suffixes of the list, we need extend/(=>>)...
GHCi> N.fromList [1..6] =>> product =>> sum
1956 :| [1236,516,156,36,6]
If we had a co-do-notation for comonads (cf. this package and the links therein), the example above might get rewritten as something in the vein of:
-- codo introduces a function: x & f = f x
N.fromList [1..6] & codo xs -> do
ys <- product xs
sum ys
The statements would correspond to plain values; the bound variables (xs and ys), to comonadic values (in this case, to list suffixes). That is exactly the opposite of what we have with monadic do-blocks. All in all, as far as your question is concerned, switching to comonads just swaps which things we can't refer to outside of the context of a computation.

"For all" statements in Haskell

I'm building comfort going through some Haskell toy problems and I've written the following speck of code
multipOf :: [a] -> (Int, a)
multipOf x = (length x, head x)
gmcompress x = (map multipOf).group $ x
which successfully preforms the following operation
gmcompress [1,1,1,1,2,2,2,3] = [(4,1),(3,2),(1,3)]
Now I want this function to instead of telling me that an element of the set had multiplicity 1, to just leave it alone. So to give the result [(4,1),(3,2),3] instead. It be great if there were a way to say (either during or after turning the list into one of pairs) for all elements of multiplicity 1, leave as just an element; else, pair. My initial, naive, thought was to do the following.
multipOf :: [a] -> (Int, a)
multipOf x = if length x = 1 then head x else (length x, head x)
gmcompress x = (map multipOf).group $ x
BUT this doesn't work. I think because the then and else clauses have different types, and unfortunately you can't piece-wise define the (co)domain of your functions. How might I go about getting past this issue?
BUT this doesn't work. I think because the then and else clauses have different types, and unfortunately you can't piece-wise define the (co)domain of your functions. How might I go about getting past this issue?
Your diagnosis is right; the then and else must have the same type. There's no "getting past this issue," strictly speaking. Whatever solution you adopt has to use same type in both branches of the conditional. One way would be to design a custom data type that encodes the possibilities that you want, and use that instead. Something like this would work:
-- | A 'Run' of #a# is either 'One' #a# or 'Many' of them (with the number
-- as an argument to the 'Many' constructor).
data Run a = One a | Many Int a
But to tell you the truth, I don't think this would really gain you anything. I'd stick to the (Int, a) encoding rather than going to this Run type.

How do I use the Supply monad to create a function that generates globally unique names?

Background:
I'm doing a code translation project that requires me to generate variable names. None of the names I generate should be duplicates of each other.
I'm really frustrated since this would be stupidly simple and elegant with a Python generator function.
What I've tried:
The way I was doing it before was to pass a counter variable down through recursive calls to my translate code, and pass the (possibly incremented) counter back up in the return value of basically every function.
This was really messy: it added an extra parameter to keep track of to each of these functions; and worse still it forced me to work with messy tuple return values where I would otherwise have a simple unary return value.
I've never really gotten proficient with monads in my short time with Haskell, but I had an inkling that I could use a wrapper on the State monad to simulate a global counter variable. After 3 days of messing around trying to grok monads and make one of my own, then trying to alter someone else's monads to generate the values I needed, I've finally resigned myself to straight-up using someone else's high-level monad (perhaps with a few alterations.)
My problem now:
I've identified the MonadSupply and MonadUnique modules as a couple which likely provide the simple kind of interface I need. Unfortunately I can't figure out how to use them.
In particular the MonadSupply module documentation provides this nice example use case:
runSupplyVars x = runSupply x vars
where vars = [replicate k ['a'..'z'] | k <- [1..]] >>= sequence
Looks like what I want! Once I got the module to compile I checked the type of this function in the interpreter:
> :t runSupplyVars
runSupplyVars :: Supply [Char] a -> Identity (a, [[Char]])
I've tried passing lots (hours worth) of different things to this function, with no success. I also tried passing the function to some various other functions to see if they would provide the parameters I needed implicitly. No luck so far.
The Questions:
Could someone please provide an example use case of this runSupplyVars function?
Would it be possible to do what I'm thinking with it? I want to have a function I can call from anywhere in the program, which will provide me with a different variable name or integer on each call.
To actually use the Supply monad you should structure your code with do notation and call the supply function when you actually need a name.
For example, this will produce a new variable name prefixed with var_, just to show how you might get something from the supply and use it:
newVar :: Supply [Char] [Char]
newVar = do
name <- supply
return ("var"_++name)
You'll need to structure your whole program around the Supply monad and then only call runSupplyVars once at the top-level, otherwise different parts of the program will have independent supplies and so might reuse the same variable name.
Finally, you'll need runIdentity from Control.Monad.Identity to unpack the result of runSupplyVars into the underlying tuple of type (a, [[Char]]), and then throw away the second value which is just the (infinite) list of unused names. You might be better off redefining runSupplyVars to do this for you:
import Control.Monad.Identity
[...]
runSupplyVars :: Supply [Char] a -> a
runSupplyVars x = fst (runIdentity (runSupply x vars))
where vars = [replicate k ['a'..'z'] | k <- [1..]] >>= sequence
Here's a more complete example putting it all together. Note the different monads with which do notation is used - IO for the main function, and Supply [Char] for realProgram and probably most of the rest of the code in a bigger version:
import MonadSupply
import Control.Monad.Identity
main :: IO ()
main = do
let result = runSupplyVars realProgram
print result
realProgram :: Supply [Char] Int
realProgram = do
x <- newVar
return 0
newVar :: Supply [Char] [Char]
newVar = do
name <- supply
return ("var_"++name)
runSupplyVars :: Supply [Char] a -> a
runSupplyVars x = fst (runIdentity (runSupply x vars))
where vars = [replicate k ['a'..'z'] | k <- [1..]] >>= sequence

Haskell Type Misunderstanding assigning variables

Complete noob to haskell here, i'm trying to make this following piece of code work:
It's intent is to take the first exp elements of a list, concatenate them, then call the same function again.
order ( i ) (l1)(l2) =
do exp <- (2 ^ i)
l <- (take exp l1) ++ (take exp l2 ) ++ (order (i+1) (drop exp l1) (drop exp l2));
return l
I'm sure this is far from idiomatic haskell, but you have to start some where though.
The error I am getting is on the
exp <- (2 ^ i )
saying that
No instance for (Num [Int])
arising from a use of `^'
Possible fix: add an instance declaration for (Num [Int])
which i am really unsure what this exactly means. Isn't both 2 and i integers, and then applying the exponentiation function will result in an integer?
Thanks!
I've rewritten your code as follows and added a main.
order _ [] [] = []
order i l1 l2 =
(take exp l1) ++ (take exp l2)
++ (order (i+1) (drop exp l1) (drop exp l2))
where
exp = 2^i
main = print $ order 1 [1,2,3,4] [3,4,5,6]
The first mistake you make is that your recursion doesn't terminate as order will always call itself again. The second mistake is in the use of do, this introduces a monad and considering you are new to Haskell, I would stay clear a bit. Use it only for I/O for now.
I hope this helps.
P.S: The error message you are getting is saying that a list of Int is used in a numeric way and there is no default implementation for that. This is probably caused by the do where the monad is over lists, but I'll leave it to cracks in Haskell to give an exact explanation.
All statements in a do block must belong to the same monad. This includes the right hand side of <- bindings. Therefore, because the right hand side of the second statement take exp l1 ++ ... is a list, the compiler infers that the type of 2^i must be a list as well.
This is because <- does more than just assign variables. In the case of the list monad, it sequentially binds the variable on the left to each element of the list on the right.
If you just want to bind a variable without any additional effects in a do block, you should use a let binding instead of <-.
do let exp = 2^i
l <- take exp l1 ++ ...
return l
That said, the use of do notation here is redundant. The monad laws guarantee that do x <- m; return x is the same as just m, so you can just write it directly as
order i l1 l2 = take exp l1 ++ ...
where exp = 2^i
In addition to Bryan's points, I think I can help explain the reason you got that specific error.
The big reason is that exp <- 2 ^ i in a do block does not mean "let exp be a name for the value of 2 ^ i" (You would express that meaning in a do block as let exp = 2 ^ i, but a do block isn't really what you want here anyway).
What exp <- 2 ^ i means is "let exp be a name for a value yielded by the monadic value 2 ^ i". Try reading the <- as "comes from" rather than "is". What exactly "comes from" means depends on the monad involved. So for this line to mean something, 2 ^ i must be a value in some kind of monad. Specifically, it's type is something like Monad m => m a, for unknown m and a.
Because the ^ operator works on numeric values, it returns something of type Num a => a. So that allows us to figure out that 2 ^ i should be something of type (Monad m, Num (m a)) => m a, for unknown m and a.
exp is extracted from this mystery m a, so it is of type a. The next line includes expressions like take exp l1. take requires its first argument to be of type Int, and so exp must be of type Int, and so we can tell that that unknown a we were working with must be Int. So 2 ^ i is now known to be of type (Monad m, Num (m Int)) => m Int; it is some sort of monadic integer.
In this line you also have l <- (take exp l1) ++ .... So l also "comes from" some sort of monadic value. The right hand side can be seen to be some sort of list (due to the use of ++, take, and drop). The monad involved in a do block must be the same throughout, and the list type constructor is indeed a monad. So if (take exp l1) ++ ... is a list of something, then 2 ^ i must also be a list of something.
So now we have 2 ^ i being of type [Int] (we originally knew it was m a; the m is the list type constructor [], and the a is Int). But we also know (from the use of the ^ operator) that it must be a member of the Num type class. There is no instance of Num for [Int], which is exactly the error you got.
That's just one of many inconsistencies that can be derived from the code you wrote; it's just the first one that GHC happened to encounter while trying to analyse it.

Resources