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

use*_*370 2 parallel-processing haskell

我在NFData上课时遇到了一些麻烦Control.DeepSeq.我希望我的类型能够fmap使用该Control.Parallel.Strategies模块并行实现其Functor .例如,在以下代码中,我收到错误,"无法推断(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)
Run Code Online (Sandbox Code Playgroud)

aug*_*tss 7

对不起,那是不可能的.如果你看一下fmap你可以看到它使用rdeepseq哪个需要a列表里面的类型Foo在课堂上NFData.但是没有地方可以附加这个约束,因为在实例声明中的任何地方都没有提到该类型变量.

有许多使用非标准版本的变通方法Functor,但它们都不令人愉快.

看看Haskell Type Constraints Unleashed是否有建议的解决方案.


ham*_*mar 5

你不能这样做的原因基本上是你无法定义Monadfor 的实例的原因Data.Set.

考虑Functor类的定义:

class Functor f where
    fmap :: (a -> b) -> (f a -> f b)
Run Code Online (Sandbox Code Playgroud)

仿函数类需要所有类型的参数化,brdeepseq代码中的使用试图将其限制为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` ()
Run Code Online (Sandbox Code Playgroud)