0

I am trying to figure out the mechanism to transform a generic function with n arguments into a function where each of the n argument is wrapped inside a context.

A simple example in pseudo-Haskell, where the wrapped type is tuple:

wrap :: (a1 -> a2 -> a3 -> ...) -> Context c -> ((c, a1) -> (c, a2) -> (c, a3) -> ...)

The container which holds the contexts is suggested by the alias Context c, for which I'm yet to figure out a reasonable form. For example it could be an n-tuple, a list of cs or even a composition of type (c -> c -> c -> ...).

It would most likely have to do with some ingenious use of applicative functors or monads, but I currently have no idea where to start attacking the problem. Any lead would be deeply appreciated.

Edit. Resolution

As the comments below suggest, the behaviour can be described as "give me some generic function with n arguments and [some contexts] and attach a context to each argument of the function". This resulting function will be applied applicative-style to n structures S a using some operators which are implemented to make use of these contexts, something like:

(wrap f contexts) §> s1 <§> s2 <§> s3 <§> ....

As an example, I got something running with fixed-size vectors arguments like FSVec c a. So I was wondering whether there is a method to pass a generic function of type fi :: [a1] -> [a2] -> ... and some lengths and "zip" them to get fo :: FSVec c a1 -> FSVec c a2 -> .... And even more, can it be done in a generic way, i.e. apply any arbitrary constructor, not necessarily one which uses type-level (e.g. a tuple constructor as in the example above)?

Alternate solution

Of course, I can always "zip" the contexts on the structures themselves, having to only reimplement (§>) and (<§>) to act accordingly and saving me a lot of trouble:

f §> (c1, s1) <§> (c2, s2) <§> (c3, s3) <§> ...

Still, I would like to "hide" these contexts as to separate concerns. Apart from just being a matter of style, it is actually a good mental exercise to explore the power of applicative functors and applicative-like functions.

Iedu
  • 117
  • 8
  • 3
    right now the `...` part will be the worst concern - so you should start by trying to figure out the type-signature (IMO this will not primary be a monad or applicative problem - it's more like a type-function problem right now) - so the first question: is this supposed to work for `a -> b` and `a -> b -> c`, ... or for some fixed arity? – Random Dev Feb 02 '16 at 14:00
  • 1
    I think it's worth elaborating on the situation you're in where you feel like you need this. It reminds me a bit of the `Reader` monad, but it's subtly different, I suppose. – Lynn Feb 02 '16 at 15:18
  • 1
    Also, it is always easier to write a series of functions `wrapC wrapC2 wrapC3`... à la `liftA` and `liftM`. You can throw yourself into a type-function mess, but consider if it's really worth it. You probably don't need to wrap anything bigger than a six-argument function. – Lynn Feb 02 '16 at 15:20
  • 3
    Your `wrap` currently says "give me a function and n tuples and I'll apply this function to second projections of these tuples". It's simply `f <$> t1 <*> t2 <*> t3 <*> ...`. Do you actually want the opposite — "give me a function that receives n tuples and give me n arguments and I'll attach a context to each argument and apply the function"? – effectfully Feb 02 '16 at 15:26
  • @user3237465: the second situation is exactly what I was expecting. Indeed, I got the idea from studying how applicative functors work and checking the instance implementation for `((->)r)`. I imagine an operator that works on every `r` in a composition `r -> r -> ...`, similar to how `(<*>)` behaves. – Iedu Feb 02 '16 at 19:42
  • @Lynn : I will try to elaborate the question then, and will also check how `Reader` works. – Iedu Feb 02 '16 at 19:47

0 Answers0