So I finally decided to merge the normal (what sometimes I called

*applicative*) interface with the monadic one. It was not easy to me, but I feel like doing the right thing. I thought: "If I would release this library for the first time, how you would like it to be?" The answer then was "merge both interfaces!".
As a consequence of this decision, I have to admit that my work as maintainer has been reduced considerably. Now HaTeX-meta is deprecated, until HaTeX needs a similar tool, and I have about the half of modules to maintain.

Although the version has been bumped to 3.3 (being a major revision), everything code that worked until today must to work now. The only change you may need to do is to drop de .Monad in the import list. If you have some issue, please, make me know it.

*I hope all you feel happy with this.*

**About the implementation**

All I did is to define the following class:

class (Monoid l,IsString l) => LaTeXC l where

liftListL :: ([LaTeX] -> LaTeX) -> [l] -> l

liftListL :: ([LaTeX] -> LaTeX) -> [l] -> l

It allows to lift any function over LaTeX to a function over any type l of the class, as follows:

fromLaTeX :: LaTeXC l => LaTeX -> l

fromLaTeX l = liftListL (\_ -> l) []

liftL :: LaTeXC l => (LaTeX -> LaTeX) -> l -> l

liftL f x = liftListL (\[x] -> f x) [x]

liftL2 :: LaTeXC l => (LaTeX -> LaTeX -> LaTeX) -> l -> l -> l

liftL2 f x y = liftListL (\[x,y] -> f x y) [x,y]

fromLaTeX l = liftListL (\_ -> l) []

liftL :: LaTeXC l => (LaTeX -> LaTeX) -> l -> l

liftL f x = liftListL (\[x] -> f x) [x]

liftL2 :: LaTeXC l => (LaTeX -> LaTeX -> LaTeX) -> l -> l -> l

liftL2 f x y = liftListL (\[x,y] -> f x y) [x,y]

And you can continue with number of arguments of your desire. For N arguments:

liftLN :: LaTeXC l => (LaTeX -> ... -> LaTeX) -> l -> ... -> l

liftLN f x1 ... xN = liftListL (\[x1 ... xN] -> f x1 ... xN) [x1 ... xN]

Now we are ready to express all functions changing each LaTeX with a type l instance of LaTeXC. The idea is to separate LaTeX arguments and other arguments and apply a liftLN function in the following way:

foo :: LaTeXC l => l -> A -> B -> l -> C -> l

foo l1 a b l2 c = liftL2 (\l1 l2 -> old l1 a b l2 c) l1 l2

where

old :: LaTeX -> A -> B -> LaTeX -> C -> LaTeX

Here, the function old is the original definition of foo. There are plenty of examples in the library (all funcions are now defined this way). As a contributor you may want to see it.

*Since LaTeX and LaTeXT are instances of LaTeXC, now all functions work at the same time for both types.*

**The User's Guide**

I started to write the HaTeX User's Guide. I'm doing it open source. It contains an introduction and explain some basics of HaTeX. The source code repository lives here.

The release in Hackage will be done when the User's Guide becomes more complete.

## No comments:

Post a Comment