
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