3

「Strictable」タイプのクラスを作成しようとしています。その理由は、次のように定義したいからです。

foldl'' f z = foldl' f (make_strict z)

そのため、型でfold''使用すると、未評価のstrictableサンクはありません。

だから私は次のことから始めました:

{-# LANGUAGE TypeFamilies #-}

class Strictable a where
  type Strict a :: *
  make_strict :: a -> Strict a

Ints およびs のインスタンスを定義するFloatのは簡単foldl'です。これらは既に正常に機能しているため、何もする必要はありません。

instance Strictable Int where
  type Strict Int = Int
  make_strict = id

instance Strictable Float where
  type Strict Float = Float
  make_strict = id

ここがトリッキーな部分です。foldl'最も外側のコンストラクターのみをラップ解除するため、たとえばペアを使用すると、foldl'. 通常のペアから厳密なペアを作成したい。だから私はこれを試しました:

instance (Strictable a, Strictable b) => Strictable (a, b) where
  type Strict (a, b) = (! Strict a, ! Strict b)
  make_strict (x1, x2) = (make_strict x1, make_strict x2)

残念ながら、コンパイルエラーがたくさん発生しました。これをどのように実装すればよいですか?

4

2 に答える 2

3

このようなものをお探しですか?つまり、型のシノニムではなく、関連付けられたデータを使用します。

instance AdaptPair Bool Bool where
  data Pair Bool Bool = PBool {-# UNPACK #-}!Int {-# UNPACK #-}!Int

  fst (PBool x _) = Prelude.toEnum x
  snd (PBool _ x) = Prelude.toEnum x
  curry f x y    =  f (PBool (Prelude.fromEnum x) (Prelude.fromEnum y))

必要な厳密性注釈を追加するには、型のシノニムではなく、関連するデータ型を使用する必要があります。そして、あなたがそこにいる間に、モノモロタイプのいくつかを明示的にアンパックすることもできます。

強打パターンを追加するだけの一般的なインスタンスは、その後簡単です。

于 2012-06-19T17:46:15.540 に答える
2

私があなたの質問を正しく理解していて、並列戦略(PDF リンク) を理解していれば、並列戦略を簡単に実装できますmake_strictparallelAPI のパッケージと並列戦略の実装を参照してください。

実際、 のrdeepseq戦略Control.Parallel.Strategiesまさにあなたが探しているものかもしれません。

名前に「並列」という名前が付いていますが、これは実際には遅延を利用して計算を宣言的に指定し、データ構造を再帰的に下降させて、やその要素などの関数を選択的に適用することによって実装される評価戦略です。seqparpseq

于 2012-06-19T18:04:29.883 に答える