用变态链接值

use*_*407 5 haskell functional-programming recursion-schemes

假设我的定义如下(其中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
Run Code Online (Sandbox Code Playgroud)

我想知道是否有某种方法可以修改的定义,cata以便可以链接诸如a的对象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 Code Online (Sandbox Code Playgroud)

然后run计算结果为“ a0 && a1”或类似的值,即两个常量不会被标记为同一事物。

J. *_*son 4

只需将它们作为单子排序即可。

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
Run Code Online (Sandbox Code Playgroud)