在Parallel.Strategies中使用fmap会产生NFData错误

时间:2011-05-26 00:06:27

标签: haskell parallel-processing

我在NFData中的Control.DeepSeq课时遇到了一些问题。我希望我的类型使用fmap模块并行实现其Functor Control.Parallel.Strategies。例如,在以下代码中,我收到错误,“无法推断(NFData b)...”。如果我使用rseq代替rdeepseq则没有问题,但我想尝试使用rdeepseq。我在Ubuntu 11.04下运行GHC 6.12.3。

module Main where

import Control.Parallel.Strategies
import Control.DeepSeq

data Foo a = Foo Int [a]
  deriving (Show,Eq)

instance Functor Foo where
  fmap f (Foo i xs) = Foo i (map f xs `using` parList rdeepseq)

2 个答案:

答案 0 :(得分:7)

抱歉,这是不可能的。如果您查看自己的fmap,就可以看到它使用rdeepseq a,其中Foo内的列表中的NFData类型需要在班级Functor中。但是没有地方可以附加这个约束,因为在实例声明中没有提到该类型变量。

使用{{1}}的非标准版本有各种变通办法,但其中没有一个是令人愉快的。

查看Haskell Type Constraints Unleashed建议的解决方案。

答案 1 :(得分:5)

您无法执行此操作的原因基本上与您无法为Monad定义Data.Set的实例的原因相同。

考虑Functor类的定义:

class Functor f where
    fmap :: (a -> b) -> (f a -> f b)

仿函数类要求所有类型b的参数化,而在代码中使用rdeepseq会将其限制为NFData b => b

解决方法是将评估与fmap分开,例如为NFData定义Foo个实例:

instance Functor Foo where
    fmap f (Foo i xs) = Foo i (map f xs)

instance NFData a => NFData (Foo a) where
    rnf (Foo i xs) = i `seq` (xs `using` parList rdeepseq) `seq` ()