applicative-quoters-0.1.0.3: Control/Applicative/QQ/Idiom.hs
{-# LANGUAGE TemplateHaskell, QuasiQuotes #-}
-- | Idiom brackets. Vixey's idea.
module Control.Applicative.QQ.Idiom (i) where
import Control.Applicative ((<*>), pure)
import Control.Monad ((<=<))
import Language.Haskell.Meta (parseExp)
import Language.Haskell.TH.Lib
import Language.Haskell.TH.Quote
import Language.Haskell.TH.Syntax
-- ghci> [$i| (,) "foo" "bar" |]
-- [('f','b'),('f','a'),('f','r'),('o','b'),('o','a'),('o','r'),('o','b'),('o','a'),('o','r')]
i :: QuasiQuoter
i = QuasiQuoter { quoteExp = applicate <=< either fail return . parseExp }
applicate :: Exp -> ExpQ
applicate (AppE f x) =
[| $(applicate f) <*> $(return x) |]
applicate (InfixE (Just left) op (Just right)) =
[| pure $(return op) <*> $(return left) <*> $(return right) |]
applicate x = [| pure $(return x) |]