公式のIdrisチュートリアルのいくつかの例を読んで遊んでいると、怠惰な評価に関してちょっと混乱しました。イドリスが先行評価を使用してチュートリアルに記載された、および遅延評価を使用して、彼らはこれがIdrisの怠惰な評価について混乱しました
ifThenElse : Bool -> a -> a -> a
ifThenElse True t e = t
ifThenElse False t e = e
適切ではない例を与えるために行くと、彼らはその後、一例を示すように進むと
ifThenElse : Bool -> Lazy a -> Lazy a -> a
ifThenElse True t e = t
ifThenElse False t e = e
私は読んでいる間に物事を試してみたいので、非怠け者と怠惰な人をテストするための非効率なフィボナッチ関数を作成しましたifThenElse
。イドリスが先行評価を実施しなければならないことを考えると
fibo : Nat -> Nat
fibo Z = Z
fibo (S Z) = S Z
fibo (S(S Z)) = S(S Z)
fibo (S(S(S n))) = fibo (S(S n)) + fibo (S n)
-- the non lazy
ifThenElse1 : Bool -> (t: a) -> (f: a) -> a
ifThenElse1 False t f = f
ifThenElse1 True t f = t
-- should be slow when applied to True
iftest1 : Bool -> Nat
iftest1 b = ifThenElse1 b (fibo 5) (fibo 25)
-- the lazy
ifThenElse2 : Bool -> (t: Lazy a) -> (f: Lazy a) -> a
ifThenElse2 False t f = f
ifThenElse2 True t f = t
-- should be fast when applied to True
iftest2 : Bool -> Nat
iftest2 b = ifThenElse2 b (fibo 5) (fibo 25)
、私はiftest1
の実行がTrueに適用しても(fibo 25)
によって減速することが予想されます。ただし、Trueに適用すると、iftest1
とiftest2
の両方が非常に高速に実行されます。だから、怠け者/熱心に対する私の理解は根本的に欠陥がありますか?
Idrisの怠惰と熱意の違いを観察する良い例は何ですか?
私はコンパイルされたコードの違いを見ることができるはずですか?私は、 'iftest1'関数のブール値を作成するために使用されるユーザー入力を受け取るメイン関数を作成しようとしました。私は実行可能ファイルにファイルをコンパイルし、それを実行し、いくつかの入力を与えた。しかし、 'iftest1'はあたかも怠け者であるかのように振る舞います。フィボナッチ関数を非合計にしようとしましたが、何も変更されませんでした。怠惰と熱心さを観察するためのよりよい例は何でしょうか? (そのような例を作成することが全く可能な場合) – Michelrandahl
'b:Bool'をいくつかの入力に依存させて、' iftest1 b'をコンパイル時に減らすことはできません。 – xash