Haskell делает нотацию и сопоставление с образцом? - PullRequest
2 голосов
/ 03 октября 2019

Так вот мой код ..

move :: [Char] -> [Char] -> IO ()
move f t = do { putStrLn ("Moving from \"" ++ f ++ "\" to \"" ++ t ++ "\"!") }

hanoi :: Integer -> [Char] -> [Char] -> [Char] -> IO ()
hanoi 0 f _ _ = do { putStrLn ("Lane \""++ f ++ "\" empty!") }
hanoi n f h t = do { hanoi (n - 1) f t h
                   ; move f t
                   ; hanoi (n - 1) h f t } 

Когда я выполняю Ханой 4 "A" "B" "C" Я ожидаю что-то подобное:

Moving from "A" to "B"!
Moving from "A" to "C"!
Moving from "B" to "C"!
Moving from "A" to "B"!
Moving from "C" to "A"!
Moving from "C" to "B"!
Moving from "A" to "B"!
Tower "A" empty!
...

Но я получаю:

Tower "A" empty!
Moving from "A" to "B"!
Tower "C" empty!
Moving from "A" to "C"!
Tower "B" empty!
Moving from "B" to "C"!
Tower "A" empty!
Moving from "A" to "B"!
Tower "C" empty!
Moving from "C" to "A"!
Tower "B" empty!
Moving from "C" to "B"!
...

Мне кажется, что существует некоторая проблема с сопоставлением с шаблоном и с обозначением и я не могу понять, что. Может кто-нибудь объяснить мне, что я делаю не так или нет, я полагаю, что что-то связано с асинхронным выполнением монады ввода-вывода.

Я новичок в Haskell, и до сих пор не совсем понял монады .. .

1 Ответ

3 голосов
/ 03 октября 2019

Я не знаю, где твое недоразумение, но ты, вероятно, слишком рано обвиняешь монаха-монстра. Трассировка этой программы в 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).

...