是否可以使用包围语法糖作为应用函子?

时间:2012-08-17 23:50:06

标签: haskell syntactic-sugar template-haskell applicative

McBride and Paterson's 'Applicative programming with effects'中,他们为解除纯粹的功能引入了一些可爱的语法糖:

[| f x y z |]

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

我想起了使用li f w x y z ilil f v w x y z li的其他人,我想/可能是因为它可以使用现有语言功能和li的狡猾定义来定义il

除了本文之外,我找不到任何对此的参考,并且假设[||]不太可能在ghc中很快出现,是否可以实现{{ 1}}和li不知何故?我不能为他们想出一个合理的类型,所以我假设我需要模板Haskell或类似,但不知道几乎足以实现这一点。 il会很好,但我不知道在我开始尝试它之前是否可能,如果是的话,肯定需要帮助。

3 个答案:

答案 0 :(得分:16)

我认为this正是您所寻找的。如果我没记错的话,还有关于这种应用方式的haskell-cafe邮件列表的讨论。

答案 1 :(得分:14)

通过使用haskell-src-meta包来解析准引用中的Haskell表达式,可以很容易地在Template Haskell中实现。

{-# 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"

请注意,由于模板Haskell的工作原理,您无法使用定义它的同一文件中的quasiquoter,因此请将上述内容保存到自己的模块中。

在GHCi中进行测试

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

答案 2 :(得分:8)

模板Haskell的方法是由Matt Morrow编写的,然后由我在applicative-quoters package中维护。您将其用作[i| f x y z |],因此它与McBride和Paterson的原创理念相当接近。

(可能的缺点:名称i不应该被您的代码遮蔽,否则它将无法正常工作。不确定这是多么大的交易,个人而言。