-1

これらの数行のエラーは非常に小さいため、自分ではわかりません。

これが私のコードです:

askName = do
  putStr "Type your name: "
  name <- getLine
  return name

sayHelloTo name = do
  when (null name) (name <- askName)

どうやらそれはエラーを与える:

1 of 1] Compiling Main             ( test.hs, interpreted )

test.hs:9:30: parse error on input `<-'
Failed, modules loaded: none.

なにか提案を?

編集 1.

私が書いても同じ:

sayHelloTo name = do
  when (null name) (name2 <- askName)
4

2 に答える 2

9

このname2 <-構文は do 表記の一部であり、doブロック内でのみ使用できます。また、変数の代入ではありませんname2。内部的には、パラメーターとして持つコールバック関数を作成しているだけです。

つまり、次のコードです。

do
    name2 <- monadicOp
    ...things...

脱糖する

monadicOp >>= (\name2 -> ...things... )

これが、Haskell で物を代入したり変更したりしないことを明確にするのに役立つことを願っています。

とにかく、特定の問題を解決するには、if-then-else (実際には?:三項演算子と同等のもの) を使用して適切な値を返すことができます。たとえば、次の関数は再帰を使用して、満足のいく結果が得られるまで何度も名前を尋ねます。

getNonEmptyName :: IO String
getNonEmptyName = do
    name <- getName
    if null name --note: indenting if statements in do blocks is tricky
       then getNonEmptyName
       else (return name)

または、do表記シュガーなし:

getNonEmptyName = getName >>= (\name -> if (null name) then getNonEmptyName else (return name) )

これはあなたが慣れ親しんでいるものとは少し違うかもしれませんが、これがどのように機能するかを理解したら、supをクリアできるはずです. 基本的getNonEmptyNameに typeIO Stringです。つまり、実行時に文字列を生成する IO アクションの IO アクションです。IO Stringその値は getNonEmptyName の戻り値になるため、if-then-else 部分も値として評価されるはずです。最初に getNonEmptyName への再帰呼び出しを実行し (そして、必要に応じて IP 文字列値が得られます)、else ブランチで return 関数を使用して通常の文字列値 (名前) を IO 文字列に昇格させるため、これはすべて正常に機能します。

于 2013-01-08T19:00:51.827 に答える
4

sayHelloTo何をするべきか、何を返すべきかは完全には明らかではありません - 確かに変更するつもりはありませんname- しかし、推測では、次のようなことを意味するかもしれません

 sayHelloTo :: String -> IO String
 sayHelloTo name
   | null name   = askName
   | otherwise   = return name
于 2013-01-08T18:53:32.933 に答える