Haskell 使用递归方案全局应用本地匹配/重写
我想使用“本地”重写器重写树:Haskell 使用递归方案全局应用本地匹配/重写,haskell,recursion-schemes,Haskell,Recursion Schemes,我想使用“本地”重写器重写树: {-# LANGUAGE FlexibleContexts, DeriveFoldable, TemplateHaskell, TypeFamilies, DeriveFunctor, DeriveTraversable #-} import Control.Applicative import Data.Functor.Foldable import Data.Functor.Foldable.TH import Data.Maybe 因此,我编写了r
{-# LANGUAGE FlexibleContexts, DeriveFoldable, TemplateHaskell,
TypeFamilies, DeriveFunctor, DeriveTraversable #-}
import Control.Applicative
import Data.Functor.Foldable
import Data.Functor.Foldable.TH
import Data.Maybe
因此,我编写了rewriteGlobal
函数,在树中的不同点应用相同的match
。它接受一个“本地”Rewrite t
,并返回一个全局。我只在树上行走一次,在没有更多的重写之前,不会尝试对每个树节点应用多次重写
但是,有两种方法可以重写树。每次重写都在已重写的子树(带子树
模式)或“原始”子树(不带子树
模式)上进行。在后一种情况下,较高的重写“获胜”
忽略对t
的约束,rewriteGlobal
的类型为:
data SKI = S | K | I | App SKI SKI deriving (Show)
makeBaseFunctor ''SKI
type Rewrite a = a -> Maybe a
match :: Rewrite SKI
match x = case x of
App I x -> Just x
_ -> Nothing
下面是一个实现:
data ChildRewrites = WithChildren | WithoutChildren
rewriteGlobal :: ChildRewrites -> Rewrite t -> Rewrite t
问题是:是否有专门为本地重写设计的特定结构/方法?只有在不存在这种专门方法的情况下,这才是基于意见的,而一般方法是我能做的最好的方法
rewriteGlobal flag rewriteFn = para $ liftA2 (<|>)
(rewriteFn . handleChildren flag)
liftChildRewrites
handleChildren WithChildren = embed . fmap (uncurry fromMaybe)
handleChildren WithoutChildren = embed . fmap fst
liftChildRewrites cons | any (isJust . snd) cons = Just $ handleChildren WithChildren cons
liftChildRewrites _ = Nothing
test = App I $ App S $ App I $ K
bar = [rewrite WithChildren match test, rewrite WithoutChildren match test]