Sco*_*uff 6 haskell coding-style pointfree
你能转换吗?
-- tupleUnfold :: forall a. ((forall b. a -> b)) -> a -> ((b))
tupleUnfold :: Int -> ExpQ
tupleUnfold n = do
  xs <- forM [1 .. n] (const . newName $ "x")
  y <- newName "y"
  let y' = varE y
      g (ps', es') x = (varP x : ps', appE (varE x) y' : es')
      (ps, es) = foldl' g ([], []) xs
  lamE [tupP ps, varP y] (tupE es)
在保持清晰度的同时采用无点风格(我知道程序'pointfree',但更愿意不再混淆代码)?
无论哪种方式,可以做出哪些改变来改进功能的风格,或者使其意图更清晰?该功能旨在如下使用.
$(tupleUnfold 3) ((+ 1), (+ 2), (+ 3)) 2
-- (3, 4, 5)
有哪些更好的命名约定(请参阅ps,ps',es和es'变量)?
这就是我得到的.需要Control.Arrow (&&&)和Control.Applicative (<$>).
tupleUnfold :: Int -> ExpQ
tupleUnfold n = do
    y <- newName "y"
    (ps,es) <- unzip . map (varP &&& (`appE` varE y) . varE) 
                <$> replicateM n (newName "x")
    lamE [tupP ps, varP y] (tupE es)
如果不让它完全不可理解,就不能再贬低它了.
编辑虽然不是免费的,但这是我能做到的最清晰的.需求Data.Function (on)
tupleUnfold :: Int -> ExpQ
tupleUnfold n = do
    y <- newName "y"
    xs <- replicateM n (newName "x")
    let exps = tupE $ zipWith appVars xs (repeat y)
        pats = tupP $ map varP xs
    lamE [pats, varP y] exps
  where
    appVars = appE `on` varE