20

McBride 和 Paterson 的“带效果的应用程序编程”中,他们引入了一些可爱的语法糖来提升纯函数:

[| f x y z |]

为了

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

我记得有人在其他地方使用li f w x y z ilor il f v w x y z li,我认为/希望这可能是因为它可以使用一些现有的语言特性和 and 的巧妙定义来li定义il

除了论文之外,我找不到任何对此的参考,并且假设[|并且|]不太可能很快出现在 ghc 中,是否有可能以li某种方式实施il?我想不出适合他们的类型,所以我假设我需要 Template Haskell 或类似的东西,但我知道的还不够多。[af| f x y ]会很好,但在我开始尝试之前我不知道这是否可能,如果是的话,当然需要帮助。

4

3 回答 3

16

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.

于 2012-08-18T06:53:50.193 回答
14

这很容易在 Template Haskell 中实现,方法是使用haskell-src-meta包来解析准引用中的 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"

请注意,由于 Template Haskell 的工作原理,您不能从定义它的同一文件中使用准引用器,因此请将上述内容保存到其自己的模块中。

在 GHCi 中测试

*Main> :set -XTemplateHaskell
*Main> :set -XQuasiQuotes
*Main> [af|(+) (Just 3) (Just 8)|]
Just 11
*Main> [af|(+) (Just 6) Nothing|]
Nothing
于 2012-08-18T06:59:49.213 回答
8

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

(可能的缺点:名称i不应该被您的代码所掩盖,否则它将不起作用。个人不确定这有多大意义)。

于 2012-08-23T17:07:25.747 回答