2

私は英語を話すのが苦手で申し訳ありません。

以下のコードを見てみましょう。

main = getChar

最初に main が評価され、その値は "getChar" ですが、コンパイラは "getChar" の値を認識していないため、コンパイラは "getChar" を評価して "getChar" の値を計算するため、getChar が実行されます。

実際に上記のコードをテストしたとき。"getChar が実行されます。

以下のコードを見てみましょう。

main = return (getChar, getChar)

最初にメインが評価され、その値は return (未定義、未定義) -> IO (未定義、未定義) であるため、プレリュードは IO (未定義、未定義) を評価して値を出力します。したがって、2 つの getChar のうちの 1 つが評価されます。

しかし、上記のコードをテストしたところ、2 つの getChar のいずれも評価されませんでした。2 つの getChar のいずれも評価されない理由がわかりません。

4

2 に答える 2

4

実際にモナド アクションを実行してから、その実行結果を返す必要があります。

func = do
    a <- getChar
    b <- getChar
    return  (a,b)

現在行っていることは、C ステートメントのようなものです。

void main(char &a, char &b)
{
    a = getchar;
    b = getchar;
}

あなたが本当に欲しいものとは対照的に:

void main(char &a, char &b)
{
    a = getchar();
    b = getchar();
}
于 2012-05-13T00:41:41.947 に答える
0

「2 つの getChar のいずれも評価されない理由を知りたい」

まず、英語では、論理、数学、または Haskell のように、(not (not p)) == p です。したがって、質問は次のようになります。

2 つの getChars の両方が評価される理由を知りたいです。

どれも評価されていないに違いないので、紛らわしいです。

メイン関数は IO a の値を計算し、タイプ a の IO 内の値が評価されます。あなたの場合、 a は (IO Char, IO Char) です。Haskell は非厳密な言語であるため、タプルを評価することは単にタプルを構築することを意味します。これには、タプル コンポーネントの評価は含まれません。例えば:

fst (42, 7 `quot` 0 :: Int)

ゼロ除算エラーで中止されません。したがって、次のようになります。

(getChar, getChar) 

2 つの未評価の値を持つタプルです。しかし、値が評価されたとしても、タイプ IO Char の 2 つの値があります。このような値は、IO モナドで実行されたときに Char を返すアクションとして見ることができます。

したがって、タプル コンポーネントが評価されないだけでなく、IO モナドでも実行されません。

これを実現するには、2 つのアクションを含むタプルを別のアクションに渡すことができます。

executeBoth (a,b) = do
    ra <- a
    rb <- b
    return (ra, rb)

さて、executeBoth のタイプを確認してください。おそらく要点がわかります。

于 2012-05-13T08:22:34.817 に答える