
Wow, that's very general. So you want to divide hanoi
into a main function, a helper function, and a display
function.
I tried it out, and got this far so far:
hanoi :: a -> a -> a -> Int -> [(a, a)]
hanoi a b c n = hanoi_helper a b c n
hanoi_helper :: a -> a -> a -> Int -> [(a, a)]
hanoi_helper source using dest n
| n == 1 = [(source, dest)]
| otherwise = hanoi_helper source dest using (n-1)
++ hanoi_helper source using dest 1
++ hanoi_helper using source
dest (n-1)
hanoi_shower :: Show a => [(a, a)] -> String
hanoi_shower [(a, b)] = "Move " ++ show a ++ " to " ++
show b ++ "."
However, when I tried to run the code in WinHugs, this
is what I got:
Hugs> :load hanoi_general.hs
Main> putStr (hanoi_shower (hanoi 'a' 'b' 'c' 2))
Program error: pattern match failure: hanoi_shower
[('a','b'),('a','c')] ++ ([] ++ hanoi_helper 'b' 'a'
'c' (2 - 1))
There seems to be a bug in hanoi_shower.
I'm still trying to debug hanoi_shower, but I need to
stop for today and continue on this tomorrow.
Thanks for your help so far! Perhaps I can get this
general version fully working tomorrow.
Benjamin L. Russell
--- Tillmann Rendel
Benjamin L. Russell wrote:
Ok; much better. Here's my new type signature and definition:
hanoi :: Int -> IO () hanoi_helper :: Char -> Char -> Char -> Int -> [String]
If you want, you can separate the algorithm and the output processing even more by providing three functions of these types:
hanoi :: Int -> [(Char, Char)] hanoi_helper :: Char -> Char -> Char -> Int -> [(Char, Char)] hanoi_shower :: [(Char, Char)] -> String
and at the interpreter level:
putStr (hanoi_shower (hanoi 2))
added value: you can easily use the output of hanoi for automated processing (e.g. testing, controlling a robot, producing an animation, counting the number of steps).
You can go one step further if you consider that towers don't have to be named by single characters, but can be named by everything:
hanoi :: a -> a -> a -> Int -> [(a, a)] hanoi_helper :: a -> a -> a -> Int -> [(a, a)] hanoi_shower :: Show a => [(a, a)] -> String
now you can use
putStr (hanoi_shower (hanoi 'a' 'b' 'c' 2))
to get the same result as above, but you are also allowed to write
putStr (hanoi_shower (hanoi 1 2 3 2))
if you want to use numeric tower names.
Tillmann _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe