如何为递归单例类型定义 NFData 实例?

2024-04-21

我在用着singletons图书馆。我有这个数据类型:

import Control.DeepSeq
import Data.Singletons.Prelude
import Data.Singletons.TH

data T =
      A
    | B [T]

genSingletons [''T]

我想要生成单例类型ST成为NFData。 如果输入,那就很简单了T不会是递归的。 我尝试这样写:

instance NFData (ST a) where
    rnf SA = ()
    rnf (SB (x `SCons` xs)) = rnf x `seq` rnf xs

但这在最后一行失败并显示消息:

Could not deduce (NFData (Sing n1)) arising from a use of `rnf'
from the context (a ~ 'B n)
  bound by a pattern with constructor
             SB :: forall (z_azEs :: T) (n_azEt :: [T]).
                   (z_azEs ~ 'B n_azEt) =>
                   Sing n_azEt -> Sing z_azEs,
           in an equation for `rnf'
or from (n ~ (n0 : n1))
  bound by a pattern with constructor
             SCons :: forall (a0 :: BOX) (z0 :: [a0]) (n0 :: a0) (n1 :: [a0]).
                      (z0 ~ (n0 : n1)) =>
                      Sing n0 -> Sing n1 -> Sing z0,
           in an equation for `rnf'
In the second argument of `seq', namely `rnf xs'
In the expression: rnf x `seq` rnf xs
In an equation for `rnf':
    rnf (SB (x `SCons` xs)) = rnf x `seq` rnf xs

我了解 GHC 想要x and xs在模式中SB (x ``SCons`` xs))成为NFData,但我很难弄清楚如何准确地讲述这一点。 我应该在这个实例的上下文中写什么才能使其工作?


首先,您需要提供NFData单例列表的实例。

instance NFData (SList '[]) where
  rnf SNil = ()

instance (NFData (Sing x), NFData (SList xs)) => NFData (SList (x ': xs)) where
  rnf (SCons x xs) = rnf x `seq` rnf xs

请注意,您无法在单个实例中解决此问题,因为这样您就无法提供递归NFData限制:

instance NFData (SList xs) where
  rnf SNil = ()
  rnf (SCons x xs) = ? -- no way to know if NFData (Sing x)

同样,您必须为T cases:

instance NFData (ST A) where
  rnf SA = ()

instance NFData (SList xs) => NFData (ST (B xs)) where
  rnf (SB xs) = rnf xs
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何为递归单例类型定义 NFData 实例? 的相关文章

随机推荐