Я не знаю, где твое недоразумение, но ты, вероятно, слишком рано обвиняешь монаха-монстра. Трассировка этой программы в Haskell кажется идентичной трассировке через ее довольно прямой C-аналог, который дает то же, что вы показали:
// move :: [Char] -> [Char] -> IO ()
void move(char *f, char *t)
{
// move f t = do { putStrLn ("Moving from \"" ++ f ++ "\" to \"" ++ t ++ "\"!") }
printf("Moving from \"%s\" to \"%s\"!\n", f, t);
}
// hanoi :: Integer -> [Char] -> [Char] -> [Char] -> IO ()
void hanoi(int64_t n, char *f, char *h, char *t)
{
if (0 == n) {
// hanoi 0 f _ _ = do { putStrLn ("Lane \""++ f ++ "\" empty!") }
printf("Lane \"%s\" empty!\n", f);
} else {
// hanoi n f h t =
hanoi(n-1,f,t,h); // hanoi (n - 1) f t h
move(f,t); // move f t
hanoi(n-1,h,f,t); // hanoi (n - 1) h f t
}
}
int main()
{
hanoi(4,"A","B","C");
return 0;
}
Подумайте, что происходит. Вы сказали hanoi 4 ...
, и следующая строка кода любого значения - hanoi (4 - 1) ...
, за которой, как уже заметил @ user2407038, последуют hanoi 2
, hanoi 1
и hanoi 0
.
* 1010. * Я думаю, вы должны рассмотреть свой алгоритм более тщательно.
[некоторая проблема с] сопоставлением с образцом и сделать запись
Хотя эти понятия не совсем не связаны, эти понятия довольно различны. Единственный шаблон, который у вас есть, - 0
, и у вас нет шаблонов из-за привязок в ваших блоках do (например, [some pattern] <- move
).