
Thanks, all, that gives me something to chew on.
It occurred to me (during my 45-minute commute to work) that all Haskell
programs (listen to the noob <eyeroll/>) have the following structure
(modulo my fractured syntax):
main :: IO()
main = do
inputs <- getInputs
doOutput $ f inputs initialState
f :: [input] -> state -> outputs
f [] state =
transformToOutputs state
f (input:inputs) state =
f inputs (newState state input)
doOutput :: [output] -> IO()
doOutput outputs = do
putStr $ unlines outputs
So all I have to do is write newState and I'm good! ^_^
(transformToOutputs will, of course, be a snap.)
Right?
John.
On Thu, Dec 15, 2016 at 2:38 PM, Magnus Therning
John Lusk
writes: I have not, but I might. This was a little work project that I've now run out of time for.
I was really hoping for a deeper discussion of state management than "just use this package." This seems kind of like receiving a stream of inputs from a user and needing to keep track of several items of state that are changing independently (as opposed to the neat problems usually used in basic FP education).
Should I be taking a more monadic approach?
Well, we have to start somewhere :)
Anyway, you don't necessarily have to resort to the state monad. I believe, based you your other code that you quite easily can go from your list of lines to a list of `(Int, String)`, where the integer indicates the indentation level. Then you can look at `Data.Tree` (in containers) and `Data.Tree.Zipper` (in rosezipper) to build your tree.
This is my quick hack:
~~~ buildTree _ zipPos [] = zipPos buildTree n zipPos xx@((lvl, s):xs) | lvl > n = let newZipPos = children zipPos node = Node s [] in buildTree lvl (insert node newZipPos) xs | lvl == n = let newZipPos = nextSpace zipPos node = Node s [] in buildTree lvl (insert node newZipPos) xs | lvl < n = let (Just newZipPos) = parent zipPos in buildTree (n - 1) newZipPos xx ~~~
With the following definitions in place:
~~~ ils = [ (1, "The root") , (2, "Child 1") , (3, "Child 1.1") , (4, "Child 1.1.1") , (3, "Child 1.2") , (2, "Child 2") ]
zipRoot = fromTree $ Node "absolute top" [] ~~~
I build the tree, and print it, like this:
~~~ putStrLn $ drawTree $ toTree $ buildTree 0 zipRoot ils top | `- The root | +- Child 1 | | | +- Child 1.1 | | | | | `- Child 1.1.1 | | | `- Child 1.2 | `- Child 2 ~~~
Whether this is usable for you depends a lot on how big your logs are, I suppose.
If this was something that I'd keep around for a while I'd probably look into rewriting `buildTree` so that it would fit for use with `mapAccumL`.
/M
-- Magnus Therning OpenPGP: 0x927912051716CE39 email: magnus@therning.org jabber: magnus@therning.org twitter: magthe http://therning.org/magnus
The British have "the perfect temperament to be hackers—technically skilled, slightly disrespectful of authority, and just a touch of criminal behavior". — Mary Ann Davidson, Oracle's Security Chief
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners