Hackage ライブラリのアナモフィズムを使用して壊れたfilter
関数を実装しました。recursion-schemes
import Data.Functor.Foldable
xfilter :: (a -> Bool) -> [a] -> [a]
xfilter f = ana $ project . phi f
phi :: (a -> Bool) -> [a] -> [a]
phi f (h : t) | not (f h) = t
phi f l = l
filter
この関数は:の忠実な実装ではありませんxfilter odd [1..5]
が、機能xfilter odd [0,0]
しません。で明示的な再帰を使用して「再試行」を実装しようとしたphi
後、それをパラモーフィズムで再実装したため、次のように終了しましたana . para
。
xfilter :: (a -> Bool) -> [a] -> [a]
xfilter f = ana . para $ phi where
phi Nil = Nil
phi (Cons h (t, tt)) | f h = Cons h t
phi (Cons h (t, tt)) = tt
これで問題ありませんが、再試行を明示的に表現しphi
、外部で実行しようとしました。
xfilter :: (a -> Bool) -> [a] -> [a]
xfilter f = ana $ project . retry (phi f)
phi :: (a -> Bool) -> [a] -> Either [a] [a]
phi f (h : t) | not (f h) = Left t
phi f l = Right l
retry f x = case f x of
Right x -> x
Left x -> retry f x
Right
は「新しい要素を生成する」ことをLeft
意味し、「新しいシードで再試行する」ことを意味します。
の署名はphi
、リストに特化したアポモーフィズムの最初の引数にかなり似ているように見え始めました。
xxapo :: ([a] -> Prim [a] (Either [a] [a])) -> [a] -> [a]
xxapo = apo
([a] -> Either [a] [a]
対[a] -> Prim [a] [a] (Either [a] [a]
)
だから、アポモルフィズムやその他の一般化された展開を使用してフィルタリングを実装することは可能ですか、ana . para
それとも私が期待できる最高のものですか?
折り畳みを使用できることは知っていますが、問題は特に展開に関するものです。