Skip to content

Instantly share code, notes, and snippets.

@pierric
Last active September 17, 2016 07:07
Show Gist options
  • Save pierric/a307bb792d17e7e6751f43120873569f to your computer and use it in GitHub Desktop.
Save pierric/a307bb792d17e7e6751f43120873569f to your computer and use it in GitHub Desktop.
{-# LANGUAGE TemplateHaskell #-}
import Language.Haskell.TH
{--
-- collect the results of expressions as a tuple,
-- e1 >>= \a ->
-- e2 >>= \b ->
-- return (a,b)
-- for example:
*Main> let es n = mapM (\i -> [|return i|]) [1..n]
*Main> $( es 5 >>= tupled . map return )
(1,2,3,4,5)
*Main> $( es 5 >>= listed . map return )
[1,2,3,4,5]
--}
collect :: ([ExpQ] -> ExpQ) -> [ExpQ] -> ExpQ
collect cl es = do
let n = length es
as <- sequence (replicate n (newName "a"))
let ret :: ExpQ
ret = appE (varE $ mkName "return") (cl $ map varE as)
bind :: (Name, ExpQ) -> ExpQ -> ExpQ
bind (a,e) r = appE (appE (varE $ mkName ">>=") e) (lam1E (varP a) r)
foldr bind ret $ zip as es
tupled :: [ExpQ] -> ExpQ
tupled = collect tupE
listed :: [ExpQ] -> ExpQ
listed = collect listE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment