それは完全には正しくありません(そして私のためにコンパイルされません)。値n+1
は正しいですが、まったく正しい方法で使用されていません。多分あなたはオペレーターセクションを使うつもりでしたか?
factorial n' = fact n' id
where
id = \x -> x
fact 0 cont = cont 1
fact (n+1) cont = fact n (cont . (* (n+1)))
これは、次のものと同じです(ただし、より鈍感です)。
factorial n' = fact n' id
where
id = \x -> x
fact 0 cont = cont 1
fact (n+1) cont = fact n (\ret -> cont (ret * (n+1)) )
ここで変更することがいくつかあります。まず、id
これは標準関数なので、再定義する必要はありません。次に、これらの例では「n + kパターン」を使用しています。これは、GHCではデフォルトでIIRCが使用できなくなりました。「n+kパターン」の代わりに、通常のパターン変数を使用できます。1
ベースケースに使用したことに注意してください。これは、からカウントダウンするかどうかを推論するのが簡単n
であり、継続関数は計算内の各ステップで適用する必要があります(誘導ステップから削除しました)。これらを念頭に置いて、あなたは書くことができます
factorial n' = fact n' id
where
fact 0 cont = cont 1
fact n cont = fact (n-1) (cont . (* n))
これは多かれ少なかれ慣用的だと思います。
編集:私は個人的にn + kパターンが好きではありませんが、それらを説明するのに少し時間がかかると思いました。ベースケースと帰納法のステップを使った数学的帰納法を考えると、わかりやすいと思います。基本ケースはfact 0 ...
です。次に、基本ステップから進んで他の値を定義します。「いずれの場合も、この関係によってfact n k
決定します。」fact (n+1) k
これは、私が通常のパターン変数を考える方法とは異なります。つまり、ここでのボトムアップではなくトップダウンですが、それは動機と、一部の人々がスタイルを好む理由を説明していると思います。
n + kパターンが気に入らない理由は、定義が雑然としているからですが、YMMVです。