Question

In McBride and Paterson's 'Applicative programming with effects' they introduce some lovely syntactic sugar for lifting a pure function:

[| f x y z |]

for

f <$> x <*> y <*> z

and I recall someone somewhere else using li f w x y z il or il f v w x y z li, and I thought/hoped that might be because it could be defined using some existing language feature and cunning definition of li and il.

I can't find any reference to this beyond the paper, and assuming that [| and |] aren't likely to turn up in ghc any time soon, is it possible to implement li and il somehow? I can't think of a sensible type for them, so I assume I'd need Template Haskell or similar, but don't know nearly enough to accomplish this. [af| f x y ] would be fine, but I don't know whether it's possible before I start attempting it, and certainly need help if it is.

Was it helpful?

Solution

This is pretty easy to implement in Template Haskell by using the haskell-src-meta package to parse the Haskell expression in the quasi-quotation.

{-# LANGUAGE TemplateHaskell #-}

import Language.Haskell.TH
import Language.Haskell.TH.Quote
import Language.Haskell.Meta (parseExp)

import Control.Applicative ((<*>), (<$>))

af = QuasiQuoter
    { quoteExp  = parseAf
    , quotePat  = undefined
    , quoteType = undefined
    , quoteDec  = undefined
    }

parseAf :: String -> Q Exp
parseAf s = case parseExp s of
    Right ex -> applyExp ex
    Left err -> fail err

applyExp :: Exp -> Q Exp
applyExp (AppE f@(AppE _ _) a) = [|$(applyExp f) <*> $(return a)|]
applyExp (AppE f a) = [|$(return f) <$> $(return a)|]
applyExp _ = fail "invalid expression in af"

Note that due to how Template Haskell works, you can't use the quasiquoter from the same file where it's defined, so save the above to its own module.

Testing in GHCi

*Main> :set -XTemplateHaskell
*Main> :set -XQuasiQuotes
*Main> [af|(+) (Just 3) (Just 8)|]
Just 11
*Main> [af|(+) (Just 6) Nothing|]
Nothing

OTHER TIPS

I think this is what you are looking for. If I remember correctly there has also been a discussion on the haskell-cafe mailing list regarding this style of applicative applications.

The Template Haskell approach to this was written by Matt Morrow and then maintained by me, in the applicative-quoters package. You use it as [i| f x y z |], so it's reasonably close to McBride and Paterson's original idea.

(Possible drawback: the name i should not be shadowed by your code, else it won't work. Not sure how big a deal this is, personally).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top