为什么Template Haskell会添加意想不到的parens?

时间:2015-05-05 07:44:40

标签: haskell template-haskell

我有以下内容:

import Control.Applicative
import Control.Monad
import Language.Haskell.TH


mkExp :: [Name] -> ExpQ
mkExp (name:[]) = [| ZipList $(varE name) |]
mkExp (name:names) = [| ZipList $(varE name) <*> $(mkExp names) |]

zipN :: Int -> ExpQ
zipN n = do
  names <- mapM newName $ replicate n "x"
  fn <- newName "f"
  let vps = map varP (fn:names)
  lamE vps $ [| $(varE fn) <$> $(mkExp names) |]

我希望生成$(zipN 2)

\f x y -> f <$> ZipList x <*> ZipList y

使其具有(a -> b -> c) -> [a] -> [b] -> [c]类型。但是从-ddump-splices的输出中搜索并滤除了噪音,我发现$(zipN 2)会生成:

\f x y -> f <$> ((ZipList x) <*> (ZipList y))

类型(a -> b) -> [a1 -> a] -> [a1] -> ZipList b。同样,$(zipN 3)会生成:

\f x1 x2 x3 -> (f <$> ((ZipList x1) <*> ((ZipList x2) <*> (ZipList x3)))

所以看起来$([|...|])的每个实例都被替换为(...)而不是...,这对我来说是令人惊讶的,因为文档似乎说成对{{1} }和$( )“已取消。”

为什么Template Haskell会生成这个AST,我该怎么做才能从中获取一个具有正确类型的函数?

0 个答案:

没有答案