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 il
或il f v w x y z li
,我想/希望,也许是因为它可以使用一些现有的语言功能和狡猾的定义来定义li
和il
.
我无法找到超越纸本的任何参考,并假设[|
并|]
不太可能在GHC任何时间很快转起来,是有可能实现li
并il
不知何故?我不能为他们想出一个合理的类型,所以我假设我需要模板Haskell或类似,但不知道几乎足以实现这一点.[af| f x y ]
没关系,但我不知道在我开始尝试它之前是否可能,如果确实需要帮助.
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)
模板Haskell的方法由Matt Morrow编写,然后由我在应用程序 - 引用程序包中维护.你使用它[i| f x y z |]
,因此它与McBride和Paterson最初的想法相当接近.
(可能的缺点:名称i
不应该被您的代码遮蔽,否则它将无法工作.不确定这是多大的交易,个人而言).