[Haskell-beginners] Applicative Functors: Rose Trees with an
alternate behavior
Travis Erdman
traviserdman at yahoo.com
Tue Aug 10 03:49:51 EDT 2010
The rose trees implemented in Data.Tree behave in the same way as the applicative style on lists (ie all possible combinations/permutations). I need a different behavior: one-to-one application.
So, using the Data.Tree code, if I start with this tree:
*Main Data.Traversable> putStrLn $ drawTree (fmap show temp2)
1
|
+- 2
|
`- 3
and then try this:
*Main Data.Traversable> putStrLn $ drawTree (fmap show $ sequenceA [temp2,temp2])
[1,1]
|
+- [1,2]
|
+- [1,3]
|
+- [2,1]
| |
| +- [2,2]
| |
| `- [2,3]
|
`- [3,1]
|
+- [3,2]
|
`- [3,3]
It gives all the combinations/permutations. I need this:
*Main Data.Traversable> putStrLn $ drawTree (fmap show $ seqA [temp2,temp2])
[1,1]
|
+- [2,2]
|
`- [3,3]
But then only way I could get that result was to (re-)write my own sequenceA function (called it seqA), which I suspect shouldn't be necessary. If I use the built-in sequenceA, I get (only) this:
*Main Data.Traversable> putStrLn $ drawTree (fmap show $ sequenceA [temp2,temp2])
[1,1]
Here's my code:
data Tree a = Node {fromNode :: !a, fromNodeForest :: !(Forest a)}
deriving (Show, Eq)
type Forest a = [Tree a]
zipWithForest = zipWith
emptyForest = []
instance Functor Tree where
fmap f (Node x subtrees) = Node (f x) (fmap (fmap f) subtrees)
instance Applicative Tree where
pure x = Node x emptyForest
(<*>) (Node f tfs) (Node cargo subtrees) = Node (f cargo) (zipWithForest (<*>) tfs subtrees)
seqA :: (Applicative f) => [f a] -> f [a]
seqA (x:xs) = foldr (liftA2 (:)) (fmap (const []) x) (x:xs)
I think I've got something wrong in how I've defined the Applicative Functor methods, and "cheating" by writing a custom sequenceA function to work around the deficiency. What is the proper fix?
thanks again,
travis
More information about the Beginners
mailing list