2016-09-10 5 views
0

私はcが有効でないときに最初のmainが終了せず、2番目が終了する理由を理解しようとしています。説明からhere mainはちょうど未評価のサンクであり、executingはデータ構造を構築しています。私はここで同じ原則を適用しようとしているし、最初のメインが終了しない理由を参照しようとしています。誰かが私にこの部分を理解させるのを手伝ってもらえれば、これを理解するための指針を私に与えることができます。これとは別に、GHCIはこれをTCOとして認識できないのはなぜですか? does notは定義に適合していますか?ハスケル:TCOとレイジー評価

main = loop                  
    where                   
    loop = do                 
    c <- getChar                
    case valid c of                
     Nothing -> return()              
     Just b -> print b              
    print c                  
    loop                  

> main :: IO() 
> main = loop 
> where 
> loop = do 
>  c <- getChar 
>  case validate c of 
>  Nothing -> return() 
>  Just b -> do 
>   print b 
>   loop 

ありがとうございます。

+1

['return'](http://hackage.haskell.org/package/base-4.9.0.0/docs/Control-Monad-Instances.html#v:return)は単なるライブラリ関数であり、手続き型言語の 'return'キーワードとはかなり違って動作しますか? – leftaroundabout

+0

@leftaroundabout:「POST」を押していて、すぐにこのコメントを見たとき、これについての「何か」が正しくないことに気づいた。ありがとう。 – user3169543

+0

答えを受け入れる以外の質問を「閉じる」方法はありませんか?もしそうなら、私はいつか答えを受け入れることができるまで待つ必要があります。 stackoverflowのドキュメントを読んでいます。今のところ、私は受け入れるために7分以上待っています:-)。 – user3169543

答えて

5

テールコールの最適化なしこの動作に関係します。問題は、最初のコードに無限ループが含まれ、2番目のコードに無限ループが含まれていることです。

あなたの最初のコードは、必須(Pythonのような)と類似している:

def loop(): 
    c = getChar() 
    if valid c: 
     do_something() 
    else: 
     do_something_else() 

    print(c) 
    loop() 

後者は同様である一方後者の場合にloop()への呼び出しがどのように

def loop(): 
    c = getChar() 
    if valid c: 
     do_something() 
    else: 
     do_something_else() 
     print(c) 
     loop() 

の内部ブランチelseであり、前者はの外側であり、の外側にあり、したがって、loopの呼び出しごとに呼び出されます。

また、Haskellのreturnではなく、は関数呼び出しを終了します。特定の価値を持ち、副作用がないのはちょうどIOアクションです。

例えば:

main = do 
    c <- return 1 
    print c 
上記のコードで

returnないprintからの出力を防ぎます。

関連する問題