如何使用 Haskell 中的 Control.DeepSeq 完全评估递归数据类型?
How to fully evaluate a recursive data type using Control.DeepSeq in Haskell?
我正在尝试使用 Criterion) a function, which uses a recursive data type. I found a 进行基准测试,但我无法为我的案例申请答案。对于非递归数据类型,以下工作:
data ExampleDataType1 a =
ValueConst1 String String String String
| ValueConst2 String String
| ValueConst3 a
| ValueConst4 String
deriving (Show, Eq, Ord)
instance DeepSeq.NFData a => DeepSeq.NFData (ExampleDataType1 a) where
rnf (ValueConst1 c1 c2 c3 c4) = DeepSeq.rnf c1 `seq` DeepSeq.rnf c2 `seq` DeepSeq.rnf c3 `seq` DeepSeq.rnf c4
rnf (ValueConst2 c1 c2) = DeepSeq.rnf c1 `seq` DeepSeq.rnf c2
rnf (ValueConst3 c1) = DeepSeq.rnf c1
rnf (ValueConst4 c2) = DeepSeq.rnf c2
但是,执行以下操作:
infixl 6 :+: -- Addition
infixl 7 :*: -- Multiplication
data ExampleDataType2 a =
ValueConst5 (ExampleDataType2 a)
| a :*: String
| (ExampleDataType2 a) :+: (ExampleDataType2 a)
| ValueConst6 String a
| ValueConst7 String a
deriving (Show, Eq, Ord)
type MapExample a b = Map.Map String (Either (ExampleDataType1 a) (ExampleDataType2 b))
data ExampleDataType3 a b = ExampleDataType3 {
start :: String,
mapList :: [MapExample a b]
} deriving Show
instance DeepSeq.NFData a => DeepSeq.NFData (ExampleDataType1 a) where
rnf (ValueConst1 c1 c2 c3 c4) = DeepSeq.rnf c1 `seq` DeepSeq.rnf c2 `seq` DeepSeq.rnf c3 `seq` DeepSeq.rnf c4
rnf (ValueConst2 c1 c2) = DeepSeq.rnf c1 `seq` DeepSeq.rnf c2
rnf (ValueConst3 c1) = DeepSeq.rnf c1
rnf (ValueConst4 c2) = DeepSeq.rnf c2
instance DeepSeq.NFData b => DeepSeq.NFData (ExampleDataType2 b) where
rnf (ValueConst5 c1) = DeepSeq.rnf c1
rnf (val1 :+: val2) = DeepSeq.rnf val1 `seq` DeepSeq.rnf val2
rnf (val :*: str) = DeepSeq.rnf val `seq` DeepSeq.rnf str
rnf (ValueConst6 str val) = DeepSeq.rnf str `seq` DeepSeq.rnf val
rnf (ValueConst7 str val) = DeepSeq.rnf str `seq` DeepSeq.rnf val
instance (DeepSeq.NFData a, DeepSeq.NFData b) => DeepSeq.NFData (ExampleDataType3 a b) where
rnf (ExampleDataType3 s lst) = DeepSeq.rnf s `seq` DeepSeq.rnf lst
在我希望进行基准测试的函数上调用 Criterion.Main
的 nf
函数时导致错误,该函数具有签名 testFunction :: (Show a1, Integral a1, Num a2, Eq a2) => [[a1]] -> ExampleDataType3 a2 a1
:
• Ambiguous type variable ‘a20’ arising from a use of ‘nf’
prevents the constraint ‘(Control.DeepSeq.NFData
a20)’ from being solved.
Probable fix: use a type annotation to specify what ‘a20’ should be.
These potential instances exist:
instance [safe] (Control.DeepSeq.NFData a,
Control.DeepSeq.NFData b) =>
Control.DeepSeq.NFData (Either a b)
-- Defined in ‘Control.DeepSeq’
instance (Control.DeepSeq.NFData k, Control.DeepSeq.NFData a) =>
Control.DeepSeq.NFData (Map.Map k a)
-- Defined in ‘Data.Map.Internal’
instance Control.DeepSeq.NFData a =>
Control.DeepSeq.NFData (Set.Set a)
-- Defined in ‘Data.Set.Internal’
...plus 20 others
...plus 150 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
对于应如何全面评估递归数据类型的每一个答案,我将不胜感激。
编辑 1:
导致错误的基准调用:
main = defaultMain [
bgroup "TestCases" [ bench "Case 1" $ nf testFunction [[1,0,1,1],[0,0,0,1],[1,1,1,0],[0,1,0,1]]
]]
函数 testFunction
完成了它的工作,除了我未能完全评估递归数据类型,因此 Criterion 的 nf
函数可以接受我的函数作为输入。因此,我想避免更改数据类型。
您可以将类型签名添加到 testFunction
,然后将其传递给 nf
。类似于:
nf (testFunction :: [[Int]] -> ExampleDataType3 Double Int) [[1,0,1,1],[0,0,0,1],[1,1,1,0],[0,1,0,1]]
我选择了Double类型;你可以选择其他类型。由于有多个选项,GHC 给出了 Ambiguous type variable
错误,而不是任意选择一个。
我正在尝试使用 Criterion) a function, which uses a recursive data type. I found a
data ExampleDataType1 a =
ValueConst1 String String String String
| ValueConst2 String String
| ValueConst3 a
| ValueConst4 String
deriving (Show, Eq, Ord)
instance DeepSeq.NFData a => DeepSeq.NFData (ExampleDataType1 a) where
rnf (ValueConst1 c1 c2 c3 c4) = DeepSeq.rnf c1 `seq` DeepSeq.rnf c2 `seq` DeepSeq.rnf c3 `seq` DeepSeq.rnf c4
rnf (ValueConst2 c1 c2) = DeepSeq.rnf c1 `seq` DeepSeq.rnf c2
rnf (ValueConst3 c1) = DeepSeq.rnf c1
rnf (ValueConst4 c2) = DeepSeq.rnf c2
但是,执行以下操作:
infixl 6 :+: -- Addition
infixl 7 :*: -- Multiplication
data ExampleDataType2 a =
ValueConst5 (ExampleDataType2 a)
| a :*: String
| (ExampleDataType2 a) :+: (ExampleDataType2 a)
| ValueConst6 String a
| ValueConst7 String a
deriving (Show, Eq, Ord)
type MapExample a b = Map.Map String (Either (ExampleDataType1 a) (ExampleDataType2 b))
data ExampleDataType3 a b = ExampleDataType3 {
start :: String,
mapList :: [MapExample a b]
} deriving Show
instance DeepSeq.NFData a => DeepSeq.NFData (ExampleDataType1 a) where
rnf (ValueConst1 c1 c2 c3 c4) = DeepSeq.rnf c1 `seq` DeepSeq.rnf c2 `seq` DeepSeq.rnf c3 `seq` DeepSeq.rnf c4
rnf (ValueConst2 c1 c2) = DeepSeq.rnf c1 `seq` DeepSeq.rnf c2
rnf (ValueConst3 c1) = DeepSeq.rnf c1
rnf (ValueConst4 c2) = DeepSeq.rnf c2
instance DeepSeq.NFData b => DeepSeq.NFData (ExampleDataType2 b) where
rnf (ValueConst5 c1) = DeepSeq.rnf c1
rnf (val1 :+: val2) = DeepSeq.rnf val1 `seq` DeepSeq.rnf val2
rnf (val :*: str) = DeepSeq.rnf val `seq` DeepSeq.rnf str
rnf (ValueConst6 str val) = DeepSeq.rnf str `seq` DeepSeq.rnf val
rnf (ValueConst7 str val) = DeepSeq.rnf str `seq` DeepSeq.rnf val
instance (DeepSeq.NFData a, DeepSeq.NFData b) => DeepSeq.NFData (ExampleDataType3 a b) where
rnf (ExampleDataType3 s lst) = DeepSeq.rnf s `seq` DeepSeq.rnf lst
在我希望进行基准测试的函数上调用 Criterion.Main
的 nf
函数时导致错误,该函数具有签名 testFunction :: (Show a1, Integral a1, Num a2, Eq a2) => [[a1]] -> ExampleDataType3 a2 a1
:
• Ambiguous type variable ‘a20’ arising from a use of ‘nf’
prevents the constraint ‘(Control.DeepSeq.NFData
a20)’ from being solved.
Probable fix: use a type annotation to specify what ‘a20’ should be.
These potential instances exist:
instance [safe] (Control.DeepSeq.NFData a,
Control.DeepSeq.NFData b) =>
Control.DeepSeq.NFData (Either a b)
-- Defined in ‘Control.DeepSeq’
instance (Control.DeepSeq.NFData k, Control.DeepSeq.NFData a) =>
Control.DeepSeq.NFData (Map.Map k a)
-- Defined in ‘Data.Map.Internal’
instance Control.DeepSeq.NFData a =>
Control.DeepSeq.NFData (Set.Set a)
-- Defined in ‘Data.Set.Internal’
...plus 20 others
...plus 150 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
对于应如何全面评估递归数据类型的每一个答案,我将不胜感激。
编辑 1:
导致错误的基准调用:
main = defaultMain [
bgroup "TestCases" [ bench "Case 1" $ nf testFunction [[1,0,1,1],[0,0,0,1],[1,1,1,0],[0,1,0,1]]
]]
函数 testFunction
完成了它的工作,除了我未能完全评估递归数据类型,因此 Criterion 的 nf
函数可以接受我的函数作为输入。因此,我想避免更改数据类型。
您可以将类型签名添加到 testFunction
,然后将其传递给 nf
。类似于:
nf (testFunction :: [[Int]] -> ExampleDataType3 Double Int) [[1,0,1,1],[0,0,0,1],[1,1,1,0],[0,1,0,1]]
我选择了Double类型;你可以选择其他类型。由于有多个选项,GHC 给出了 Ambiguous type variable
错误,而不是任意选择一个。