recursion-schemes.
Sentence sym
.
{-
import Data.Functor.Foldable -- from the recursion-schemes package
-- The functor describing the recursive data type
data SentenceF sym r
= AtomicSentence sym
| ImplySentence r r
| AndSentence r r
| OrSentence r r
| NotSentence r
deriving (Functor, Show)
-- The original type recovered via a fixed point
type Sentence sym = Fix (SentenceF sym)
Sentence sym , , Fix.
:
(Constructor ...), Fix (Constructor ...). ,
type Symbol = String
-- A simple formula: not (p -> (p || q))
testSentence :: Sentence Symbol
testSentence =
Fix $ NotSentence $
Fix $ ImplySentence
(Fix $ AtomicSentence "p")
(Fix $ OrSentence
(Fix $ AtomicSentence "p")
(Fix $ AtomicSentence "q"))
( Fix es).
-- The original code, adapted
imply_remove :: Sentence Symbol -> Sentence Symbol
imply_remove (Fix (ImplySentence s1 s2)) =
Fix $ OrSentence (Fix $ NotSentence (imply_remove s1)) (imply_remove s2)
imply_remove (Fix (AndSentence s1 s2)) =
Fix $ AndSentence (imply_remove s1) (imply_remove s2)
imply_remove (Fix (OrSentence s1 s2)) =
Fix $ OrSentence (imply_remove s1) (imply_remove s2)
imply_remove (Fix (NotSentence s1)) =
Fix $ NotSentence (imply_remove s1)
imply_remove (Fix (AtomicSentence s1)) =
Fix $ AtomicSentence s1
, imply_remove testSentence: - , :
-- Output: not ((not p) || (p || q))
Fix (NotSentence
(Fix (OrSentence
(Fix (NotSentence (Fix (AtomicSentence "p"))))
(Fix (OrSentence
(Fix (AtomicSentence "p"))
(Fix (AtomicSentence "q")))))))
, :
imply_remove2 :: Sentence Symbol -> Sentence Symbol
imply_remove2 = cata $ \case
-- Rewrite ImplySentence as follows
ImplySentence s1 s2 -> Fix $ OrSentence (Fix $ NotSentence s1) s2
-- Keep everything else as it is (after it had been recursively processed)
s -> Fix s
imply_remove2 testSentence, , .
cata? , ,
cata f, , .. ,
- , . \case . cata ( Functor, ).
, , -
recursion-schemes. cata , , (, , ).