我有以下数据类型和示例方程,我想用 futumorphism 进行转换......
import Matryoshka as M
import Data.Functor.Nu (Nu(..), observe, unfold)
data ArithmeticF a
= Mult a a
| Div a a
| Add a a
| Num Number
type Arithmetic = Nu ArithmeticF
derive instance functorArith :: Functor ArithmeticF
equation :: Arithmetic
equation = (div (n 3.0) (n 4.0)) `add` (div (n 3.0) (n 4.0))
mult :: Arithmetic -> Arithmetic -> Arithmetic
mult a b = M.embed $ Mult a b
div :: Arithmetic -> Arithmetic -> Arithmetic
div a b = M.embed $ Div a b
add :: Arithmetic -> Arithmetic -> Arithmetic
add a b = M.embed $ Add a b
n :: Number -> Arithmetic
n a = M.embed $ Num a
使用futu
这是我尝试编写一个函数以(Div (Num 1.0) (Num 4.0))
从等式中分解出来。最后,我希望生成的树是(Mult (Div (Num 1.0) (Num 4.0)) (Add (Num 3.0) (Num 3.0)))
. 这个函数类型检查但我一定做错了什么,因为它在我运行它时没有评估。
solve :: Arithmetic -> Number
solve = M.cata algebra
simplify :: Arithmetic -> Arithmetic
simplify s = M.futu factor s
factor :: GCoalgebra (Free ArithmeticF) ArithmeticF Arithmetic
factor s = case M.project s of
(Add a b) ->
case (Tuple (M.project a) (M.project b)) of
(Tuple (Div c d) (Div e f)) -> do
let dd = solve d
let ff = solve f
if dd == ff
then
Mult
(liftF $ observe (unfold dd (\m -> Div 1.0 dd )))
(liftF $ observe (unfold c (\g -> Add c e )))
else Add (liftF $ observe a) (liftF $ observe b)
_ -> Add (liftF $ observe a) (liftF $ observe b)
(Div a b) -> Div (liftF $ observe a) (liftF $ observe b)
(Mult a b) -> Mult (liftF $ observe a) (liftF $ observe b)
(Num a) -> (Num a)
main = log $ M.cata show (simplify equation)