I'm trying to get an expression and turn it into a standard form. To better clarify my purpose, assume you define a general style for your expressions like this:
∑(a*b) // sum of products
Now if you're given an input which is not in that format like: (a+b)*(c+d), you'll need to normalize it first.(Actually it is only a simple example and not my case) Now I have a code which is already written in ML and it's too long. Here you can see some snipets:
rew(p_choice(x,p_nil)) = rew(x) |
rew(p_choice(p_nil,x)) = rew(x) |
rew(p_sum(d,p_nil)) = p_nil |
rew(p_sum(d,p_choice(x,y))) = rew(p_choice(rew(p_sum(d,x)),rew(p_sum(d,y))))
rew(p_cond(b,p_nil,p_nil)) = p_nil |
rew(p_cond(b,p_choice(x,y),p_nil)) =rew(p_choice(rew(p_cond(b,x,p_nil)),rew(p_cond(b,y,p_nil)))) |
rew(p_cond(b,p_sum(x,y),p_nil)) = rew(p_sum(x,rew(p_cond(b,y,p_nil)))) |
rew(p_cond(b1,p_cond(b2,x,p_nil),p_nil)) = rew(p_cond(b1 andalso b2, x,p_nil)) |
rew(p_cond(b,x,p_nil)) = p_cond(b,x,p_nil) |
rew(p_cond(b,x,y)) =
rew(p_choice(rew(p_cond(b,x,p_nil)),rew(p_cond(not(b),y,p_nil))))
My question is, does Haskell introduce any features that can help this code be done more neatly?
The pattern matching facilities in Haskell are very similar and I don't think the biggest Haskell exclusivities (typeclasses, lazyness, etc) are going to help you. That said, there might be ways to make things simpler in ML.
One thing to consider is to divide the processing in smaller steps. Right now there is some duplication depending if things are the left or the right argument. You could try transforming to an intermediate standard form that chooses one particular order for things.
Another trick is separating the processing of each step from the recursion so you don't mix the tree traversal with the node processing. You can write functions to process the stp for each node and then you use a separate fold function to tie everything together.
data Tree = Leaf Int | Node Tree Tree
directsum :: Tree -> Int
directSum (Leaf n) = n
directsum (Node a b) = (directsum a) + (directsum b)
-- vs
foldtree :: (Int -> r) -> (r -> r -> r) -> Tree -> b
foldtree onLeaf onNode t =
go t
where
go (Leaf n) = onLeaf n
go (Tree a b) = onNode (go a) (go b)
foldedSum :: Tree -> Int
foldedsum t =
foldtree leafsum nodesum t
where
leafsum n = n
nodesum a b = a + b
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.