繁体   English   中英

如何让 GHC 识别此代码段中的 SingI 实例?

[英]How do I make the GHC recognize a SingI instance in this snippet?

有一个关于单身人士的问题

我有一个提升的数据类型a ,我a其中适当地实例化了data family Sing (a :: Foo)

我也有一个类型家族Bar (a :: Foo) (b :: Foo) :: Foo

在繁忙的功能中,我有:

(\(x :: Sing n) (y :: Sing m) -> doThingsWith (sing :: Sing (Bar n m)))

但我不确定应该把SingI约束放在SingI

有关更多详细信息,我的类型是

data PNat = NZ | NS PNat

data instance Sing (n :: PNat) where
  SNZ :: Sing 'NZ
  SNS :: Sing (m :: PNat) -> Sing ('NS m)

我的字体家族是

type family NPlus (n :: PNat) (m :: PNat) :: PNat where
  NPlus NZ y = y
  NPlus (NS x) y = NS (NPlus x y)

现在,我实际上能够手动写出显式单例改组:

nPlus :: forall n m nm. (NPlus n m ~ nm) => Sing n -> Sing m -> Sing nm
nPlus SNZ y = y
nPlus (SNS x) y = SNS (nPlus x y)

这编译得很好......我可以做到

\x y -> nPlus x y

但我觉得我应该能够在这里使用singI并让singI系列完成这两项工作。 此外,我也有很多这样的功能,我宁愿不必为每个功能都做。

我确实打开了 ScopedTypeVariables。

谢谢你们


编辑:啊,我刚刚意识到SingI实例不是自动派生的; 我挑了一个:

instance SingI NZ where
  sing = SNZ

instance SingI n => SingI (NS n) where
  sing = SNS sing

不幸的是,当我在上面的 lambda 中使用sing时,GHC 仍然告诉我没有SingI实例:/

我觉得我应该能够在这里使用 singI 并让字体系列完成这两项工作。

这是做不到的。 我们在singletons有许多 TH 设施的原因是数据和函数定义必须在当前状态下重复。

惯用的用法是在术语级别定义所有内容一次,然后用 TH 派生其余部分。

-- LANGUAGE KitchenSink
import Data.Singletons.TH
import Data.Singletons.Prelude

$(singletons [d|
  data PNat = NZ | NS PNat deriving (Eq, Show, Ord)

  nPlus :: PNat -> PNat -> PNat
  nPlus NZ y = y
  nPlus (NS x) y = NS (nPlus x y)  |])

这将创建Sing定义、 nPlus的类型族、 SingI实例、 SingKind实例、 Sing的种类限制SPNat类型同义词、类型族和构造函数的去功能化符号,以及EqOrd类型级类似物,以及可判定的平等 您可以点击模块上的:bro:i PNat以准确找出生成的内容。

现在nPlus和类型系列NPlus按预期工作。

提供一些关于SingI的解释: SingI a => t等价于Sing a -> t 他们甚至编译成完全相同的核心代码。 它们之间的唯一区别是Sing -s 是显式传递的,而SingI -s 是隐式传递的。 sing提供从SingISing转换,而singInstance向后转换。

鉴于此,类似

(SingI (NPlus n m)) => Sing n -> Sing m -> Sing (NPlus n m)

很尴尬,因为它相当于

Sing (NPlus n m) -> Sing n -> Sing m -> Sing (NPlus n m)

它可以实现为一个不做任何加法的常量函数。

那么我们什么时候应该使用SingISing呢? 最方便的方法是在Sing -s 上执行计算,因为我们可以对它们进行模式匹配,并且仅当我们只需要在某处插入或传递值时才使用SingI ,但不需要模式匹配或递归。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM