2016-08-01 19 views
0

definition of getLine in the Haskell Preludeを見ると、 私は再帰がどのように働いているのですか?改行がヒットしてIOにラップされたリストを作成するまで、文字を要求し続けます。getLineはどのようにhaskellで動作しますか?

しかし、このケースではreturnステートメントがどのように機能するのですか?具体的には、return (c:....:return "")はどのように動作しますか? return ""をどのようにリストに入れるのですか?

+0

文字列は単なる文字のリストなので、 '' ''は '[] :: [Char]'と同じですので、その空のリストに文字を入れるのは意味があります。また、 'return '' 'に直接コンセンサスしないでください。 'c:getLine'(意味がない)と' do {s < - getLine; return(c:s)} ' – Alec

+0

" "は何にも同意していないことに注意してください。 – pdexter

+3

あなたは「返品」「何かにお金を払っていると思いますか? – sepp2k

答えて

5

returnは、ほとんどの言語のような制御構造ではありません。モナドの値のコンストラクタです。のは、その種類を見てみましょう。この場合

return :: Monad m => a -> m a 

String値を与え、それがIO String値を生成します。

ifの各ブランチで評価された最後の式がreturnであることは、returnの実行が終了することを意味しません。他の式は、returnの後にになる可能性があります。 returnは、単にその引数を含む新しい単一項目のリストを作成し、リストモナドで

foo :: Int -> Int -> [Int] 
foo x y = return x ++ return y 

:リストモナドから、この単純な例を考えてみましょう。これらの2つのリストは、関数によって返された最終結果リストに連結されます。

$ return 3 :: [Int] 
[3] 
$ foo 3 4 
[3,4] 
0

do -notationはシンタックスシュガーです。

do x <- e 
    rest 

(それはIOコンテナへのコールバックを付加)

>>=flatMap又は bind操作である
e >>= \x -> rest 

と等価です。

flatMap :: IO a -> (a -> IO b) -> IO b意味は次のとおりです。タイプIO aの与えられたコンテナだから、

getLine = 
    getChar >>= \c -> 
     if c == '\n' 
     then (return []) 
     else getLine >>= \rest -> 
      return (c : rest) 

IO b

を、タイプa -> IO bのコールバックを取り付けた容器はその動作に成功したときに発生し、これは、タイプの新しいコンテナを作成します手段は? getLineはすぐに実行をgetCharIO-containerに委譲します。コールバックでは、渡された文字を分析します。その改行の場合は、IO-containerの構成である "return """を返し、すぐに空のStringを返します。 それ以外の場合は、restreturnの現在のc haracterをrestに接続して自分自身を呼び出します。 Monadインターフェイスでは、コンテナ以外のコールバックをバインドすることができないので、純粋な値をコンテナに変換するために使用されます(非常に良い理由があります)。

関連する問題