Haskell做符号和模式匹配?

Haskell do notation and pattern matching?

这是我的代码..

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 } 

当我执行 hanoi 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"!
...

在我看来 模式匹配 表示法 存在一些问题,我不知道是什么。 有人可以向我解释我做错了什么或没有到达这里吗,我想有些事情与 IO monad 的异步执行有关。

我是 Haskell 的新手,还没有完全理解 monad...

我不知道你的误解在哪里,但你可能过早地指责了 Monad boogeyman。在 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 2hanoi 1hanoi 0.

我认为你应该更仔细地考虑你的算法。

[some problem with] pattern matching and do notation

虽然并非完全无关,但这些概念却截然不同。您拥有的唯一模式是 0,由于 do 块中的绑定,您没有任何模式(即 [some pattern] <- move)。