Thu 24 Apr 2008
Generalized Hylomorphisms
Posted by Edward Kmett under Category Theory , Comonads , Haskell , Monads1 Comment
I haven't seen written up anywhere the following operator (g_hylo), defined in the spirit of generalized catamorphisms and generalized anamorphisms, which seems to follow rather naturally from the definition of both -- I'm using liftW & liftM rather than fmap to make it clear what is being lifted over what.
class Functor w => Comonad w where -- minimal definition: extend & extract or duplicate & extract duplicate :: w a -> w (w a) extend :: (w a -> b) -> w a -> w b extract :: w a -> a extend f = fmap f . duplicate duplicate = extend id liftW :: Comonad w => (a -> b) -> w a -> w b liftW f = extend (f . extract) g_hylo :: (Comonad w, Functor f, Monad m) => (forall a. f (w a) -> w (f a)) -> (forall a. m (f a) -> f (m a)) -> (f (w b) -> b) -> (a -> f (m a)) -> a -> b g_hylo w m f g = extract . hylo (liftW f . w . fmap duplicate) (fmap join . m . liftM g) . return where hylo f g = f . fmap (hylo f g) . g
In the above, w and m are the distributive laws for the comonad and monad respectively, and hylo is a standard hylomorphism. In the style of Dave Menendez's Control.Recursion code it would be a 'refoldWith' and it can rederive a whole lot of recursion and corecursion patterns if not all of them.
Anyone?

![\inference{\Gamma \vdash M:W_1 \leq \lbrace\neg U_i\rbrace_{i\leq(n-1)} & \Gamma \vdash N : W_2 \leq \neg U_n}{\Gamma \vdash (M \binampersand N) : \lbrace \neg U_i \rbrace_{i \leq n }}[$\lbrace\rbrace$-I] \inference{\Gamma \vdash M:W_1 \leq \lbrace\neg U_i\rbrace_{i\leq(n-1)} & \Gamma \vdash N : W_2 \leq \neg U_n}{\Gamma \vdash (M \binampersand N) : \lbrace \neg U_i \rbrace_{i \leq n }}[$\lbrace\rbrace$-I]](../../../latex/63ee3379bf761ad7074f3bb895da57d5.png)
![\inference{\Gamma \vdash M : \lbrace \neg U_i \rbrace_{i \in I} & \Gamma \vdash N : U & U_j = \min_{i \in I} \lbrace U_i \vert U \leq U_i \rbrace } {\Gamma \vdash M \bullet N : \perp }[$\lbrace\rbrace$-E] \inference{\Gamma \vdash M : \lbrace \neg U_i \rbrace_{i \in I} & \Gamma \vdash N : U & U_j = \min_{i \in I} \lbrace U_i \vert U \leq U_i \rbrace } {\Gamma \vdash M \bullet N : \perp }[$\lbrace\rbrace$-E]](../../../latex/b5ad9c35b4aeb655526d34f61cc0b770.png)
![\inference{}{\Gamma, x:\tau \vdash x:\tau}[var] \inference{}{\Gamma, x:\tau \vdash x:\tau}[var]](../../../latex/e645c5ec70f37ece72dd6cfe28d4f4e6.png)
![\inference{\Gamma,x:\sigma \vdash M:\tau}{\Gamma \vdash \lambda x : \sigma. M : \sigma \rightarrow \tau}[abs] \inference{\Gamma,x:\sigma \vdash M:\tau}{\Gamma \vdash \lambda x : \sigma. M : \sigma \rightarrow \tau}[abs]](../../../latex/05f05269088d58a918791c0832838cb5.png)
![\inference{\Gamma \vdash M : \sigma \rightarrow \tau & \Gamma \vdash N:\sigma}{\Gamma \vdash M N : \tau}[app] \inference{\Gamma \vdash M : \sigma \rightarrow \tau & \Gamma \vdash N:\sigma}{\Gamma \vdash M N : \tau}[app]](../../../latex/6b489a895eb7d0e43a552fdda5bd3a6a.png)
works.