2015-10-02 7 views
8

ハスケルから来て、私は怠惰(非厳密性)に関するIdrisの話を読んでいました。私はそれを実行し、それが働いたIdrisは本当に「厳密に評価されていますか?

myFact : Int -> Int 
myFact n = myIf (n == 1) 1 (n * myFact (n-1)) 

それをテストするための簡単な階乗関数を書いた最近のリリースノートをtrolled、そして次

myIf : (b : Bool) -> (t : Lazy a) -> (e : Lazy a) -> a 
myIf True t e = t 
myIf False t e = e 

に似found code!私は

myIf : (b : Bool) -> a -> a -> a 

myIfの型シグネチャを変更することによって、それを破ることにしました

> myFact 5 
120 : Int 

私はidris REPLを再読み込み、および無限再帰を期待して再びmyFact 5を走りました。私の驚いたことに、それは同じように働いた!

idrisは厳密性を避けるべきであると考えていますか?なぜこれは永遠に繰り返されませんでしたか?

私はイドリス0.9.15を使用していないし、今と連動債とのリリースノートのどれも、すべての変更を言及。よ(AT型チェッカーは、未知の値の存在下で式を評価するために必要な時間をコンパイルするので、必ずしもそう)時間をコンパイルし、時間評価のセマンティクスが異なる実行http://docs.idris-lang.org/en/latest/faq/faq.html#evaluation-at-the-repl-doesn-t-behave-as-i-expect-what-s-going-on

、およびREPLは次のとおりです。

+0

私のREPLも同じことをします。しかし、REPLで 'myFact'を':x'と呼ぶか、実行可能ファイルにコンパイルすると無限ループに陥ります。それはセマンティクスを変更したとき[イドリス先行評価]の –

+0

可能な複製(http://stackoverflow.com/questions/23149532/idris-eager-evaluation) – Cactus

答えて

15

の説明はこちらコンパイル時の概念を利便性のために使用したり、式チェッカーで式がどのように減少するかを見るのに便利です。

しかし、ここでもう少し進んでいます。 IdrisはmyIfが非常に小さい機能であり、それをインラインにすることを決めたことを発見しました。イドリスはとにかくたかった制御構造にコンパイルされますので、だから、一般的に物事Lazyを行うことを気にすることなく、myIfのような制御構造を記述することができ

myFact x = case x == 1 of 
       True => 1 
       False => x * myFact (x - 1) 

myFactをコンパイルしたときに、実際のようなビットに見えるの定義を持っています。同じことが起こります。 &&および||と短絡しています。

+0

このインライン最適化は正しいですか? – luochen1990

+0

セマンティクスは変更されていません。あなたはあなたがそれをやっているところですべての入力に対して同じ答えを得ます。 –

+0

しかし、ユーザーがいくつかの同様のコーディングスタイル(コードがもはや十分に小さくインライン化されないように変更するなど)に切り替えると、プログラムの動作を変更するのではなく、プログラムの動作を変更することを期待して、イドリスは思うだろう、何でも:ああ、もちろんあなたはそれが、この特異的な発現の終了を変更するので、私は少し手の込んだ必要があることを意味する:もはやそれは全体... EDITは変更されません。..再び – luochen1990

関連する問題