スタイル対ポイントフリーフォーム
-
26-09-2019 - |
質問
あなたが変換できます。
-- 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スタイルに明確さを維持しながら、(私はプログラムの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
他のヒント
もう少し理解できない(右から左に読むことを試みる):
tupleUnfold n = do
y <- newName "y"
uncurry lamE . ((:[varP y]) . tupP *** tupE) . unzip .
map (varP &&& (`appE` varE y) . varE) <$> replicateM n (newName "x")
編集:
処理するための矢印と機能組成物の混合
tupleUnfold n = do
y <- newName "y"
uncurry lamE . ((tupP >>> (:[varP y])) *** tupE) . unzip .
map (varP &&& (varE >>> (`appE` varE y))) <$> replicateM n (newName "x")
と(左から右へ処理機能を読み取る)主に矢印を使用して
tupleUnfold n = do
y <- newName "y"
(map (varP &&& (varE >>> (`appE` varE y))) >>> unzip >>>
((tupP >>> (:[varP y])) *** tupE) >>> uncurry lamE) <$> replicateM n (newName "x")
なお、矢印機能の(>>>)ののフリップ(。)の
と等価です個人的に私はそれはかなりすでに明らかだと思うが、これはどうます:
tupleUnfold :: Int -> ExpQ
tupleUnfold = mapM (const . newName $ "x") . enumFromTo 1 >=> \xs -> do
y <- newName "y"
let y' = varE y
g (ps', es') x = (varP x : ps', appE (varE x) y' : es')
f ps = lamE [tupP ps, varP y] . tupE
uncurry f $ foldl' g ([],[]) xs
(Control.Monadから)Kleisli組成オペレータ>=>
がpointfreeモナド関数を作成するのに有用である。
所属していません StackOverflow