3

我一直在尝试制作一类“Strictable”类型。原因是我想定义这样的东西:

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

因此,当fold''在类型上使用时strictable,不会有未评估的 thunk。

所以我从以下开始:

{-# LANGUAGE TypeFamilies #-}

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

Int为s 和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_strict直接实施您的;请参阅APIparallel和并行策略的实现。

事实上,来自的rdeepseq策略Control.Parallel.Strategies可能正是您正在寻找的。

尽管名称中有“并行”,但它实际上是一种评估策略,通过利用惰性来声明性地指定计算,然后递归地向下递归数据结构以选择性地应用函数,如seq,par及其pseq元素。

于 2012-06-19T18:04:29.883 回答