この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 文字列に昇格させるため、これはすべて正常に機能します。