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

And*_*ewC 20 haskell syntactic-sugar applicative template-haskell

McBride和Paterson的"有效的应用程序设计"中,他们介绍了一些可爱的语法糖来提升纯粹的功能:

[| f x y z |]
Run Code Online (Sandbox Code Playgroud)

对于

f <$> x <*> y <*> z
Run Code Online (Sandbox Code Playgroud)

我记得别人的地方使用li f w x y z ilil f v w x y z li,我想/希望,也许是因为它可以使用一些现有的语言功能和狡猾的定义来定义liil.

我无法找到超越纸本的任何参考,并假设[||]不太可能在GHC任何时间很快转起来,是有可能实现liil不知何故?我不能为他们想出一个合理的类型,所以我假设我需要模板Haskell或类似,但不知道几乎足以实现这一点.[af| f x y ]没关系,但我不知道在我开始尝试它之前是否可能,如果确实需要帮助.

Jan*_*sen 16

我想就是你要找的东西.如果我没记错的话,还有关于这种应用程序风格的haskell-cafe邮件列表的讨论.


sha*_*ang 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"
Run Code Online (Sandbox Code Playgroud)

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

在GHCi中进行测试

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


Ben*_*ood 8

模板Haskell的方法由Matt Morrow编写,然后由我在应用程序 - 引用程序包中维护.你使用它[i| f x y z |],因此它与McBride和Paterson最初的想法相当接近.

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