Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

In SICM they frequently make use of a kind of implicit applicative lifting (I can't remember what they call it) where you apply a vector-of-functions as if it were a function itself. In psuedo-Haskell:

    lift :: Vec (a->b) -> (a->Vec b)
    lift [] a = []
    lift f:fs = (f a):(lift fs $ a)
so that you can write natural-looking multidimensional physics expressions like

    ((fx fy fz) r)
without having to invoke macros or restructure the expression to please the compiler. I dearly wish you could do this in another scheme but so far I haven't found one. Iirc it's required for using the magnificent `scmutils` package too.

For example, `guile-scmutils`[0] says:

> Functionality not available in the port:

> Scheme extension to allow applying vectors/structures as procedures. For example rather than

    1 ]=> (pe ((up (literal-function 'x) (literal-function 'y)) 't))
    (up (x t) (y t))
> you must use

    guile> (pe ((lambda (t) (up ((literal-function 'x) t) ((literal-function 'y) t))) 't))
    (up (x t) (y t))
[0] https://www.cs.rochester.edu/~gildea/guile-scmutils/


Clojure has a really nice `juxt` function for that, which I have an implementation of in my `.guile` file.

  (define (juxt . fns)
    (lambda args
      (map (lambda (fn) (apply fn args)) fns)))


lift = sequenceA @[] @(a ->)


Did you do that by hand? I guessed you used the classic `pointfree` program, bit that gave

    lift = fix ((`ap` tail) . (. head) . flip ((.) . liftM2 (:)))
As far as I know it's not possible to get this functionality in Haskell even with clever instance magic, but I'd love to be proved wrong.


> As far as I know it's not possible to get this functionality in Haskell even with clever instance magic

It is possible to fill in basic function bodies based on their type, using ghc-justdoit (https://hackage.haskell.org/package/ghc-justdoit). That's maybe not what you meant, if you are looking for integrating pointfree into Haskell it can be added to ghci or your development environment.

    foo :: ((a -> r) -> r) -> (a -> ((b -> r) -> r)) -> ((b -> r) -> r)
    foo = (…)
In this case I wrote it because I knew about the pattern. Your lift definition is just ($)

      flip \a -> ($ a)
    = flip (&)
    = flip (flip ($))
    = ($)


Maybe you meant to write

    (??) :: Functor f => f (a -> b) -> a -> f b
    funs ?? a = fmap ($ a) funs
from lens: https://hackage.haskell.org/package/lens-5.3.2/docs/Control-...

This is valid definition of lift along a different, less interesting but more general axis.

    lift = (??) @[]


    lift = flip $ \a -> ($a)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: