On 09/23/08 01:01, Jake Mcarthur wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> The first thing I thought of was to try to apply one of the recursion
> schemes
> in the category-extras package. Here is what I managed using
catamorphism.
>
> - - Jake
>
> -
>
--------------------------------------------------------------------------------
>
>
> data Expr' a
> = Quotient a a
> | Product a a
> | Sum a a
> | Difference a a
> | Lit Double
> | Var Char
>
> type Expr = FixF Expr'
>
> instance Functor Expr' where
> fmap f (a `Quotient` b) = f a `Quotient` f b
> fmap f (a `Product` b) = f a `Product` f b
> fmap f (a `Sum` b) = f a `Sum` f b
> fmap f (a `Difference` b) = f a `Difference` f b
> fmap _ (Lit x) = Lit x
> fmap _ (Var x) = Var x
>
> identity = cata ident
> where ident (a `Quotient` InF (Lit 1)) = a
> ident (a `Product` InF (Lit 1)) = a
> ident (InF (Lit 1) `Product` b) = b
> ident (a `Sum` InF (Lit 0)) = a
> ident (InF (Lit 0) `Sum` b) = b
> ident (a `Difference` InF (Lit 0)) = a
> ident (Lit x) = InF $ Lit x
> ident (Var x) = InF $ Var x
According to:
cata :: Functor f => Algebra f a -> FixF f -> a
from:
http://comonad.com/reader/2008/catamorphism
ident must be:
Algebra f a
for some Functor f; however, I don't see any declaration
of ident as an Algebra f a. Could you please elaborate.
I'm trying to apply this to a simple boolean simplifier
shown in the attachement. As near as I can figure,
maybe the f could be the ArityN in the attachment and
maybe the a would be (Arity0 ConBool var). The output
of the last line of attachment is:
bool_eval:f+f+v0=(:+) (Op0 (OpCon BoolFalse)) (Op0 (OpVar V0))
however, what I want is a complete reduction to:
(OpVar V0)
How can this be done using catamorphisms?
{-# LANGUAGE PatternSignatures #-}
{-
Purpose:
"Try out" the use of catamorphism to simplify an expression
as far as possible.
Reference:
Post:
http://www.nabble.com/Re%3A-Is-there-already-an-abstraction-for-this--p19641692.html
Headers:
From: wren ng thornton
Newsgroups: gmane.comp.lang.haskell.cafe
Subject: Re: Is there already an abstraction for this?
Date: Wed, 24 Sep 2008 00:10:29 -0400
-}
module Main where
import Array
data Arity0 con var --nullary operators
= OpCon con -- constant
| OpVar var -- variable
deriving(Show)
data ArityN arity0
= Op0 arity0
| (:+) (ArityN arity0) (ArityN arity0)
| (:*) (ArityN arity0) (ArityN arity0)
deriving(Show)
infixl 6 :+
infixl 7 :*
instance Functor ArityN where
fmap f (Op0 e) = Op0 (f e)
fmap f ((:+) e0 e1) = (:+) (fmap f e0) (fmap f e1)
fmap f ((:*) e0 e1) = (:*) (fmap f e0) (fmap f e1)
data ConBool --boolean constants
= BoolFalse
| BoolTrue
deriving(Enum,Show,Ord,Eq,Bounded,Ix)
data VarName --varable names
= V0
| V1
| V2
deriving(Enum,Show,Ord,Eq,Bounded,Ix)
bool_eval :: ArityN (Arity0 ConBool var) -> ArityN (Arity0 ConBool var)
bool_eval e = case e of
{ (Op0 (OpCon BoolTrue ) :+ _ ) -> Op0 (OpCon BoolTrue)
; (_ :+ Op0 (OpCon BoolTrue ) ) -> Op0 (OpCon BoolTrue)
; (Op0 (OpCon BoolFalse) :+ e1 ) -> e1
; (e0 :+ Op0 (OpCon BoolFalse) ) -> e0
; (Op0 (OpCon BoolFalse) :* _ ) -> Op0 (OpCon BoolFalse)
; (_ :* Op0 (OpCon BoolFalse) ) -> Op0 (OpCon BoolFalse)
; (e0 :+ e1 ) -> (bool_eval e0) :+ (bool_eval e1)
; (e0 :* e1 ) -> (bool_eval e0) :* (bool_eval e1)
; e -> e
}
main = do
let bool_f::ArityN (Arity0 ConBool VarName) = Op0 (OpCon BoolFalse)
let bool_expr_f_plus_v0 = bool_f :+ Op0 (OpVar V0)
putStr "bool_expr:f+v0="
print bool_expr_f_plus_v0
let bool_eval_f_plus_v0 = bool_eval bool_expr_f_plus_v0
putStr "bool_eval:f+v0="
print bool_eval_f_plus_v0
let bool_expr_f_plus_f_plus_v0 = bool_f :+ bool_expr_f_plus_v0
putStr "bool_expr:f+f+f+v0="
print bool_expr_f_plus_f_plus_v0
let bool_eval_f_plus_f_plus_v0 = bool_eval bool_expr_f_plus_f_plus_v0
putStr "bool_eval:f+f+v0="
print bool_eval_f_plus_f_plus_v0
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe