如何为递归单例类型定义NFData实例? [英] How can I define NFData instance for recursive singleton type?

查看:177
本文介绍了如何为递归单例类型定义NFData实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用singletons库.我有这种数据类型:

I'm using singletons library. I have this data type:

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

data T =
      A
    | B [T]

genSingletons [''T]

我希望生成的单例类型STNFData的实例. 如果类型T不是递归的,那将很简单. 我试图写这个:

I want generated singleton type ST to be instance of NFData. It would be straightforward if type T wouldn't be recursive. I tried to write this:

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

但这在消息的最后一行失败:

but this fails on last line with message:

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希望模式SB (x ``SCons`` xs))中的xxsNFData的实例,但是我很难弄清楚该如何准确地说明这一点. 在该实例的上下文中我应该写些什么来使其起作用?

I understand that GHC wants x and xs in pattern SB (x ``SCons`` xs)) to be instances of NFData, but I have trouble figuring out how exactly to tell this. What should I write in the context of this instance to make it work?

推荐答案

首先,您需要为单例列表提供NFData实例.

First, you need to provide NFData instances for singleton lists.

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约束:

Note that you can't solve this in a single instance, because that way you couldn't provide the recursive NFData constraints:

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

类似地,您必须为T案例编写单独的实例:

Similarly, you have to write separate instances for the T cases:

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

instance NFData (SList xs) => NFData (ST (B xs)) where
  rnf (SB xs) = rnf xs

这篇关于如何为递归单例类型定义NFData实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆