Haskell Programmatically/Dynamically Define Functions - function

I'm looking for a way to dynamically define functions in Haskell, or for Haskell's idiomatic equivilent of which I'm clearly not aware.
The scenario is as follows: I have a tagWithAttrs function that generates new functions based on the provided String argument. The definition looks something like this:
tagWithAttrs :: String -> ([(String, String)] -> [String] -> String)
tagWithAttrs tagName = [...] -- Implementation ommited to save room.
h1 :: [(String, String)] -> [String] -> String
h1 = tagWithAttrs "h1"
main :: IO ()
main = putStrLn $ h1 [("id", "abc"), ("class", "def")] ["A H1 Test"]
-- Should display '<h1 id="abc" class="def">A H1 Test</h1>'.
So far so good. But the line in which I assign h1 is one of many, since I'd have to do that for every single HTML tag I'm defining. In Python, I'd loop over a list of the HTML tag names, inserting each respective result from tag_with_attrs into the dictionary returned by globals(). In short, I'd be inserting new entries into the symbol table dynamically.
What is the Haskell equivilent of this idiom?
Btw, I'm fully aware that I'm duplicating the work of many existing libraries that already do HTML tags. I'm doing this for a toy project, nothing more :)
EDIT: Some posted solutions are suggesting mechanisms that still rely on defining the end result tag functions one-by-one. This violates DRY, else I would have just done it how I was doing it. It's that DRY violation that I'm trying to side-step.

Haskell is statically typed, which means that all symbols must be type-checked at compile time. So that means you can't add entries into the symbol table at runtime.
What you want is meta-programming. Where code runs at compile time to generate other code (that you naturally and rightly feel lazy to type). That implies something like a macro system .
Haskell does not have macros, but there is template Haskell:
http://www.haskell.org/haskellwiki/Template_Haskell
As with macros, the idea is that you write a function that generates an
AST. The meta-function takes the name of the function you want to use (in your
case, div, ul, li etc) and generates the AST of a functional with that name.
A bit overkill, but if you really want to do it this is a relatively simple tutorial:
http://playingwithpointers.com/archives/615

Well, as you know Haskell is curried and functions are first class, so you really don't need any magic to do that. Just recognize that you can do stuff like:
import qualified Data.Map as M
import Data.Map (Map)
import Data.Text (Text)
type TagName = Text
type TagWithAttrs = Map TagName ([(String, String)] -> [String] -> String)
tagFuncs :: TagWithAttrs
tagFuncs =
M.fromList $
("h1", \xs ys -> zs) :
("h2", \xs ys -> zs) :
{- ... -}
[]
tagWithAttrs :: TagName -> [(String, String)] -> [String] -> String
tagWithAttrs = flip M.lookup tagFuncs
This is all regular efficient Haskell. Note: You may be tempted to define tagFuncs as a local value to tagWithAttrs by using a where clause. While this can make your code more beautiful it will also result in the map to be regenerated for each invocation of tagWithAttrs.
To dynamically insert things into the map you can make the map an argument of tagWithAttrs instead of a top level map. Another alternative is to use a concurrent variable like an MVar or (probably better) a TVar.

This can be done easily with some Template Haskell:
{-# LANGUAGE TemplateHaskell #-}
import Control.Monad (forM)
import Language.Haskell.TH
tagWithAttrs :: String -> ([(String, String)] -> [String] -> String)
tagWithAttrs tagName = undefined
$(forM ["h1", "h2", "h3"] $ \tag ->
valD (varP (mkName tag)) (normalB [| tagWithAttrs $(stringE tag) |]) [])
main :: IO ()
main = putStrLn $ h1 [("id", "abc"), ("class", "def")] ["A H1 Test"]
This generates declarations h1 = tagWithAttrs "h1", h2 = tagWithAttrs "h2", h3 = tagWithAttrs "h3", and so on. To add more, just add them to the list.
The code is a bit ugly since it's not possible to splice patterns in TH. Otherwise, we would have been able to write something like [d| $(mkName tag) = tagWithAttrs $(stringE tag) |]. Instead, we have to manually construct the declaration using TH combinators.

I think what I would do would be to define a data type for tags:
data Tag = H1 | H2 | H3 ...
deriving (Show, Eq, Ord, Enum, Bounded)
This is your single point of definition for all the tags that there are.
Then define a function that maps Tag values to the appropriate function:
tag :: Tag -> [(String, String)] -> [String] -> String
tag = tagWithAttrs . show
And then where you want to call h1, h2, h3, you instead call tag H1, tag H2, tag H3, etc.
Note that this is identical in verbosity to if you had defined functions tag_h1, tag_h2, tag_h3, etc; effectively you've just got slightly longer names (which happen to include a space). To me this is the ideal combination of DRY and "say what you mean". h1 doesn't seem like a function to me anyway; I'd actually much rather think that I was working with one function on a number of data items than that I had a giant set of functions.
If I was then unsatisfied with the speed of this (because the compiler probably won't optimize away all of the tagWithAttrs calls away) and I had determined that this was the "lowest hanging fruit" to speed up my application, I would look at memoizing tagWithAttrs or tag, but internally so as to keep the same interface. One quick possibility: pre-populate a map with all tags; you can use the Enum and Bounded instance to do this without explicitly re-listing all the tags (this is something you couldn't do with tags represented by functions or by strings). A side benefit of non-strict evaluation is that this will probably result in tagWithAttrs being evaluated exactly once for each tag that is actually used.
That would still leave a data-structure lookup on each tag call (unless the compiler is clever enough to optimise them away, which is not impossible). I doubt that would be the most significant performance bottleneck unless you've done some heavy optimisation of the rest of your program. To do all the lookups at compile time (without relying on the optimiser), I think you do need Template Haskell. I probably wouldn't go that far in this case, just because I sincerely doubt I would need it to go any faster (and I have way more available compute-time than me-time). But even if I was using Template Haskell to get the lookups done at compile-time I would prefer to not make it look like a separate top-level function for each tag; I just find "tags and a function that knows how to render tags" to be a more natural and flexible approach than "tags, which can be called to render themselves".

Write a simple code generator, input the list of tags you want, include the output as a module.

Related

'Auxiliary' function in Haskell

My lecturer at the moment has a strange habit I've not seen before, I'm wondering if this is a Haskell standard or a quirk of his programming style.
Basically, he'll often do thing such as this:
functionEx :: String -> Int
functionEx s = functionExA s 0
functionExA :: String -> Int -> Int
functionExA s n = --function code
He calls these 'auxiliary' functions, and for the most part the only advantage I can see to these is to make a function callable with fewer supplied arguments. But most of these are hidden away in code anyway and in my view adding the argument to the original call is much more readable.
As I said, I'm not suggesting my view is correct, I've just not seen it done like this before and would like to know if it's common in Haskell.
Yes, this is commonplace, and not only in functional programming. It's good practice in your code to separate the interface to your code (in this case, that means the function signature: what arguments you have to pass) from the details of the implementation (the need to have a counter or similar in recursive code).
In real-world programming, one manifestation of this is having default arguments or multiple overloads of one function. Another common way of doing this is returning or taking an instance of an interface instead of a particular class that implements that interface. In Java, this might mean returning a List from a method instead of ArrayList, even when you know that the code actually uses an ArrayList (where ArrayList implements the List interface). In Haskell, typeclasses often serve the same function.
The "one argument which always should be zero at the start" pattern happens occasionally in the real world, but it's especially common in functional programming teaching, because you want to show how to write the same function in a recursive style vs. tail-recursive. The wrapper function is also important to demonstrate that both the implementations actually have the same result.
In Haskell, it's more common to use where as follows:
functionEx :: String -> Int
functionEx s = functionExA s 0 where
functionExA s n = --function code
This way, even the existence of the "real" function is hidden from the external interface. There's no reason to expose the fact that this function is (say) tail-recursive with a count argument.
If the special case definition is used frequently, it can be an advantage to do this. For example, the sum function is just a special case of the fold function. So why don't we just use foldr (+) 0 [1, 2, 3] each time instead of sum [1,2,3]? Because sum is much more readable.

what I do for these conditions to follow FP?

I'm reading FP and I have two basic questions:
FP says function should take one input and gives single output. So what should I do with void methods? It doesn't return anything right?
FP says function should have single
resresponsibility, then how do we handle log statements inside the method? That doesn't violate the rule?
Wish to know how they handle these things in Scala, Haskell.
Thanks in advance.
I'm assuming you're reading a book called "Functional Programming", although it would help to know who the author is as well. In any case, these questions are relatively easy to answer and I'll give my answers with respect to Haskell because I don't know Scala.
So what should I do with void methods? It doesn't return anything right?
There are no void methods in a pure functional language like Haskell. A pure function has no side effects, so a pure function without a return value is meaningless, something like
f :: Int -> ()
f x = let y = x * x + 3 in ()
won't do any computation, y is never calculated and all inputs you give will return the same value. However, if you have an impure function, such as one that writes a file or prints something to the screen then it must exist in a monadic context. If you don't understand monads yet, don't worry. They take a bit to get used to, but they're a very powerful and useful abstraction that can make a lot of problems easier. A monad is something like IO, and in Haskell this takes a type parameter to indicate the value that can be stored inside this context. So you can have something like
putStrLn :: String -> IO ()
Or
-- FYI: FilePath is an alias for String
writeFile :: FilePath -> String -> IO ()
these have side effects, denoted by the return value of IO something, and the () something means that there is no meaningful result from that operation. In Python 3, for example, the print function returns None because there isn't anything meaningful to return after printing a value to the screen. The () can also mean that a monadic context has a meaningful value, such as in readFile or getLine:
getLine :: IO String
readFile :: FilePath -> IO String
When writing your main function, you could do something like
main = do
putStrLn "Enter a filename:"
fname <- getLine -- fname has type String
writeFile fname "This text will be in a file"
contents <- readFile fname
putStrLn "I wrote the following text to the file:"
putStrLn contents
FP says function should have single resresponsibility, then how do we handle log statements inside the method? That doesn't violate the rule?
Most functions don't need logging inside them. I know that sounds weird, but it's true. In Haskell and most other functional languages, you'll write a lot of small, easily testable functions that each do one step. It's very common to have lots of 1 or 2 line functions in your application.
When you actually do need to do logging, say you're building a web server, there are a couple different approaches you can take. There is actually a monad out there called Writer that lets you aggregate values as you perform operations. These operations don't have to be impure and do IO, they can be entirely pure. However, a true logging framework that one might use for a web server or large application would likely come with its own framework. This is so that you can set up logging to the screen, to files, network locations, email, and more. This monad will wrap the IO monad so that it can perform these side effects. A more advanced one would probably use some more advanced libraries like monad transformers or extensible effects. These let you "combine" different monads together so you can use utilities for both at the same time. You might see code like
type MyApp a = LogT IO a
-- log :: Monad m => LogLevel -> String -> LogT m ()
getConnection :: Socket -> MyApp Connection
getConnection sock = do
log DEBUG "Waiting for next connection"
conn <- liftIO $ acceptConnection sock
log INFO $ "Accepted connection from IP: " ++ show (connectionIP conn)
return conn
I'm not expecting you to understand this code fully, but I hope you can see that it has logging and network operations mixed together. The liftIO function is a common one with monad transformers that "transforms" an IO operation into a new monad that wraps IO.
This may sound pretty confusing, and it can be at first if you're used to Python, Java, or C++ like languages. I certainly was! But after I got used to thinking about problems in this different way makes me wish I had these constructs in OOP languages all the time.
I can answer from Haskell perspective.
FP says function should take one input and gives single output. So what should I do with void methods? It doesn't return anything right?
Because that's what actually functions are! In mathematics, every functions takes some input and gives you some output. You cannot expect some output without giving any input. void methods you see in other languages doesn't make sense in a mathematical way. But in reality void methods in other languages do some kind of IO operations, which is abstracted as IO monad in Haskell.
how do we handle log statements inside the method
You can use a monad transformer stack and lift your IO log operations to perform there. In fact, writer monad can do log operations purely without any IO activities.

When should I use val x = fn as opposed to fun x

I've just started learning Standard ML (and functional programming in general) and I've come across two different ways of defining a function.
val double = fn x => x*2:
And
fun double x = x*2;
If I understand correctly, the first one is assigning a variable to an ananonymous function. Under what circumstances should I do this instead of fun abc?
This is a style question. The fun syntax is syntactic sugar for fn, so anything that you can write with the former can also be written with the latter.
fn directly represents λ-abstraction, which means it is limited to functions of one argument (see this SO question). fun is convenient shorthand that allows you to curry a multi-argument function and bind a name to it with a single bit of syntax, so it's probably better to use fun whenever you want to do one of those things.

Haskell function definition convention

I am beginner in Haskell .
The convention used in function definition as per my school material is actually as follows
function_name arguments_separated_by_spaces = code_to_do
ex :
f a b c = a * b +c
As a mathematics student I am habituated to use the functions like as follows
function_name(arguments_separated_by_commas) = code_to_do
ex :
f(a,b,c) = a * b + c
Its working in Haskell .
My doubt is whether it works in all cases ?
I mean can i use traditional mathematical convention in Haskell function definition also ?
If wrong , in which specific cases the convention goes wrong ?
Thanks in advance :)
Let's say you want to define a function that computes the square of the hypoteneuse of a right-triangle. Either of the following definitions are valid
hyp1 a b = a * a + b * b
hyp2(a,b) = a * a + b * b
However, they are not the same function! You can tell by looking at their types in GHCI
>> :type hyp1
hyp1 :: Num a => a -> a -> a
>> :type hyp2
hyp2 :: Num a => (a, a) -> a
Taking hyp2 first (and ignoring the Num a => part for now) the type tells you that the function takes a pair (a, a) and returns another a (e.g it might take a pair of integers and return another integer, or a pair of real numbers and return another real number). You use it like this
>> hyp2 (3,4)
25
Notice that the parentheses aren't optional here! They ensure that the argument is of the correct type, a pair of as. If you don't include them, you will get an error (which will probably look really confusing to you now, but rest assured that it will make sense when you've learned about type classes).
Now looking at hyp1 one way to read the type a -> a -> a is it takes two things of type a and returns something else of type a. You use it like this
>> hyp1 3 4
25
Now you will get an error if you do include parentheses!
So the first thing to notice is that the way you use the function has to match the way you defined it. If you define the function with parens, you have to use parens every time you call it. If you don't use parens when you define the function, you can't use them when you call it.
So it seems like there's no reason to prefer one over the other - it's just a matter of taste. But actually I think there is a good reason to prefer one over the other, and you should prefer the style without parentheses. There are three good reasons:
It looks cleaner and makes your code easier to read if you don't have parens cluttering up the page.
You will take a performance hit if you use parens everywhere, because you need to construct and deconstruct a pair every time you use the function (although the compiler may optimize this away - I'm not sure).
You want to get the benefits of currying, aka partially applied functions*.
The last point is a little subtle. Recall that I said that one way to understand a function of type a -> a -> a is that it takes two things of type a, and returns another a. But there's another way to read that type, which is a -> (a -> a). That means exactly the same thing, since the -> operator is right-associative in Haskell. The interpretation is that the function takes a single a, and returns a function of type a -> a. This allows you to just provide the first argument to the function, and apply the second argument later, for example
>> let f = hyp1 3
>> f 4
25
This is practically useful in a wide variety of situations. For example, the map functions lets you apply some function to every element of a list -
>> :type map
map :: (a -> b) -> [a] -> [b]
Say you have the function (++ "!") which adds a bang to any String. But you have lists of Strings and you'd like them all to end with a bang. No problem! You just partially apply the map function
>> let bang = map (++ "!")
Now bang is a function of type**
>> :type bang
bang :: [String] -> [String]
and you can use it like this
>> bang ["Ready", "Set", "Go"]
["Ready!", "Set!", "Go!"]
Pretty useful!
I hope I've convinced you that the convention used in your school's educational material has some pretty solid reasons for being used. As someone with a math background myself, I can see the appeal of using the more 'traditional' syntax but I hope that as you advance in your programming journey, you'll be able to see the advantages in changing to something that's initially a bit unfamiliar to you.
* Note for pedants - I know that currying and partial application are not exactly the same thing.
** Actually GHCI will tell you the type is bang :: [[Char]] -> [[Char]] but since String is a synonym for [Char] these mean the same thing.
f(a,b,c) = a * b + c
The key difference to understand is that the above function takes a triple and gives the result. What you are actually doing is pattern matching on a triple. The type of the above function is something like this:
(a, a, a) -> a
If you write functions like this:
f a b c = a * b + c
You get automatic curry in the function.
You can write things like this let b = f 3 2 and it will typecheck but the same thing will not work with your initial version. Also, things like currying can help a lot while composing various functions using (.) which again cannot be achieved with the former style unless you are trying to compose triples.
Mathematical notation is not consistent. If all functions were given arguments using (,), you would have to write (+)((*)(a,b),c) to pass a*b and c to function + - of course, a*b is worked out by passing a and b to function *.
It is possible to write everything in tupled form, but it is much harder to define composition. Whereas now you can specify a type a->b to cover for functions of any arity (therefore, you can define composition as a function of type (b->c)->(a->b)->(a->c)), it is much trickier to define functions of arbitrary arity using tuples (now a->b would only mean a function of one argument; you can no longer compose a function of many arguments with a function of many arguments). So, technically possible, but it would need a language feature to make it simple and convenient.

How to change xmobar configuration on the fly

I want to switch between xmobar configurations on the fly by using key combinations. I have naively tagged the following onto my other key mods:
, ((controlMask, xK_l), xmproc <- spawnPipe "/usr/bin/xmobar /home/tony/.xmobarLrc")
, ((controlMask, xK_w), xmproc <- spawnPipe "/usr/bin/xmobar /home/tony/.xmobarWrc")
and the compiler barfs at <-. You can probably read my intention in the code. I am no Haskell expert and I'm slowly building up the environment I want by using a lego approach, but that has failed me here.
Where am I going wrong?
TIA
Well, it's quite complicated to do what you want. You can use the extensible state module from the xmonad-contrib library.
For that, you have to add a LANGUAGE pragma at the top of your xmonad configuration file:
{-# LANGUAGE DeriveDataTypeable #-}
You need it to derive the Typeable instance for the data type that stores the xmobar handle.
newtype XMobarHandle = XMobarHandle { xmhandle :: Maybe Handle } deriving Typeable
instance ExtensionClass XMobarHandle where
initialValue = XMobarHandle Nothing
Now you can define the key-binding, which retrieves the current xmobar handle from the extensible state, closes it if it is not Nothing, spawns a new one and puts it into the state.
((controlMask, xK_l), do
mh <- xmhandle `fmap` XS.get
maybe (return ()) (io . hClose) mh
xmproc <- spawnPipe "/usr/bin/xmobar /home/tony/.xmobarLrc"
XS.put $ XMobarHandle (Just xmproc)
)
You can create a function for the do block in the binding if you like. The binding for the other key is left as an exercise!
To make it compile, you still need the import statements for the modules used in this code. (I may have forgotten one, though!)
import XMonad.Util.Run
import System.IO
import qualified XMonad.Util.ExtensibleState as XS
You have to edit your logHook as well. There you have to extract the handle from extensible state just like in the keybind and give it as a parameter to the function xmobarlog.