特定の値の存続期間中、特定の計算を GHC に強制的にサンクさせる方法はありますか?
もちろん、値をレコードに配置して、計算の結果に対して遅延レコード エントリを作成し、レコードを作成して値をエントリにサンクするメーカー関数を作成することもできます。
とはいえ、必要になるたびにレコードから元の値を引き出す必要はありません。また、Haskell には、C++ や Java のようなアドホックなポリモーフィック is-a 関係はありません。
同じパラメータを持つ関数の複数の無関係な呼び出しにわたって値を記憶するためのトリックはありますか?
複数の使用法が来ることを効果的にコンパイラーに伝える、依存型の形式を使用したさまざまなトリックを漠然と想像することができました。Haskell には依存型はありませんが、暗黙のパラメーターの周りに何かありますか? ないと思いますが、聞いてみようと思いました。おそらくプラグマ?
Necklace
共通の分母と分子のベクトルとして格納された有理数の結果のベクトルが必要なデータ構造のベクトルがあると想像してください。
{-# LANGUAGE ImplicitParams #-}
import qualified Data.Vector as V
data Necklace = Necklace { ... }
necklace_length n = ...
denominator :: (necklaces :: V.Vector Necklace) => Int
denominator = V.foldl' lcm 30 $ V.map necklace_length ?necklaces
numerators :: (necklaces :: V.Vector Necklace) => V.Vector Int
numerators = V.map f ?necklaces
where f x = ... denominator ...
kittytoy :: (necklaces :: V.Vector Necklace) => Meow -> ...
kittytoy = \meow -> ... numerators ...
アプリオリにkittytoy
、それぞれ異なるパラメータで数百万回呼び出すと、GHCは同じ暗黙的なパラメータで百万回meow
呼び出すコードを生成すると予想されます。numerators
necklaces
それにもかかわらず、呼び出す必要があるのは 1 回だけであることは明らかですnumerators
が、初回?necklaces
は割り当てられるため、GHC はこの最適化に気付く可能性があります。
テンプレート haskell を使用してサンクを明示的に渡す明示的なコード リファクタリング アプローチも必要?numerators = numerators
ですnumerators :: V.Vector Int
。