假设我的定义如下(其中cata
是类同化):
type Algebra f a = f a -> a
newtype Fix f = Fx (f (Fix f))
unFix :: Fix f -> f (Fix f)
unFix (Fx x) = x
cata :: Functor f => (f a -> a) -> Fix f -> a
cata alg = alg . fmap (cata alg) . unFix
我想知道是否有某种方法可以修改
cata
的定义,以便可以通过它链接一些对象,例如int
,以便可以为alg函数中的事物(例如“a0”,“a1”)生成唯一的句柄。 ,“a2”,...等。编辑:为了使这一点更加清楚,我希望能够具有一些
cata'
函数,以便在我具有类似于以下定义的内容时data IntF a
= Const Int
| Add a a
instance Functor IntF where
fmap eval (Const i) = Const i
fmap eval (x `Add` y) = eval x `Add` eval y
alg :: Int -> Algebra IntF String
alg n (Const i) = "a" ++ show n
alg n (s1 `Add` s2) = s1 ++ " && " ++ s2
eval = cata' alg
addExpr = Fx $ (Fx $ Const 5) `Add` (Fx $ Const 4)
run = eval addExpr
然后
run
的计算结果为“a0 && a1”或类似的值,即,两个常量不会被标记为同一事物。 最佳答案
只需将它们排序为单子(monad)即可。
newtype Ctr a = Ctr { runCtr :: Int -> (a, Int) } -- is State Int
instance Functor Ctr
instance Applicative Ctr
instance Monad Ctr
type MAlgebra m f a = f (m a) -> m a
fresh :: Ctr Int
fresh = Ctr (\i -> (i, i+1))
data IntF a
= Val
| Add a a
malg :: IntF (Ctr String) -> Ctr String
malg Val = (\x -> "a" ++ show x) <$> fresh
malg (Add x y) = (\a b -> a ++ " && " ++ b) <$> x <*> y
go = cata malg
关于haskell - 用变态关系链接值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23689524/