A person on Reddit has brought this code to my attention:
main = do
let ns = [print 1, print 2, print 3]
sequence_ ns
sequence_ $ reverse ns
sequence_ $ tail ns ++ [head ns]
head ns
What's going on here is we have an array of operations that we can do stuff with, like reverse or get its tail or head.
Awesome.
What I want to do is get into individual elements and change them for good. For example, I want to be able to do something like this:
ns !! 0
and get something like [print, 1] and then change last element to, say, 3.14 so that the function would print 3.14.
Is it at all possible in Haskell or should I just go back to LISP?
AN IMPORTANT EDIT: I sort of blundered. I understand that I will need to create a new list. Is it possible to get the arguments of a function, which is a part of a list? What I want is the ability to compose functions from their identifiers/arguments and also be able to break down a function into identifier/argument before it gets evaluated.
It is a bit more complicated than in Lisp, but for metaprogramming in Haskell, you can use Template Haskell.
E.g., [|print 1|]
will be translated to
return $ AppE (VarE $ mkName "print") (LitE $ IntegerL 1)
which has the type Q Exp
(a quotation of an expression).
If you want to splice your own data into a quotation, [|print $(foo 3.14)|]
will execute foo 3.14
at compile-time.
Once you've applied a value to a function, there's no way to get it back. Try wrapping the function and its argument in a datatype that you can evaluate or decompose depending on your needs.
data App a b = App (a -> b) a
runApp (App a b) = a b
ns = [App print 1, App print 2, App print 3]
main = do
sequence_ $ map runApp ns
let ns2 = [App fun (arg^2) | App fun arg <- ns]
sequence_ $ map runApp ns2
Outputs
1
2
3
1
4
9
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With