繁体   English   中英

类型级约束编码

[英]type level constraint encoding

所以我有一个数据构造函数,我只在包含Nat的类型级别使用。 通常,如果我在类型级别传递它并且我想将Nat反映到术语级别,我需要一个KnownNat约束。 我想要做的是将此KnownNat约束编码到类型本身中,因此如果此类型出现在某处的签名中,则会在 function 的主体中推断出KnownNat约束。这意味着我将不再需要在使用站点编写KnownNat约束. 我只需要确保在构造时满足KnownNat约束。

我想为此使用 GADT 并做到了这一点:

data Foo = Foo Nat Nat

type family GetA (f :: Foo) :: Nat where
  GetA ('Foo a _) = a

type family GetB (f :: Foo) :: Nat where
  GetB ('Foo _ b) = b

data KnownFoo (f :: Foo) where
  KnownFoo :: (KnownNat (GetA f), KnownNat (GetB f)) => KnownFoo f

foo :: forall (f :: Foo) (kf :: KnownFoo f). Proxy kf -> Integer
foo _ = natVal $ Proxy @(GetA f)

但这不起作用,因为类型检查器不明白GetA fKnownNat ,即使传入了KnownFoo也是如此。有没有办法让这样的事情起作用?

我还尝试将f:: Foo完全移动到KnownFoo约束中,如下所示:

data Foo = Foo Nat Nat

type family GetA (f :: Foo) :: Nat where
  GetA ('Foo a _) = a

type family GetB (f :: Foo) :: Nat where
  GetB ('Foo _ b) = b

data KnownFoo where
  KnownFoo :: forall f. (KnownNat (GetA f), KnownNat (GetB f)) => Proxy f -> KnownFoo

type family GetFoo (kf :: KnownFoo) :: Foo where
  GetFoo ('KnownFoo (Proxy f)) = f

但是后来我没有办法编写GetFoo类型系列,因为它抱怨KnownNat

任何帮助表示赞赏!

我不确定我是否完全理解您的需求,但如果您想存储KnownNat约束,则必须有一些运行时表示。 也许这样的事情可能对你有用:

{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE RankNTypes #-}

import GHC.TypeLits

data FooC a b where
    FooR :: (KnownNat a, KnownNat b) => FooC a b

type family GetA x where GetA (FooC a b) = a
type family GetB x where GetB (FooC a b) = b

withKnowledge :: FooC a b -> ((KnownNat a, KnownNat b) => r) -> r
withKnowledge FooR r = r

请注意, DataKinds甚至不在这里:我们直接定义我们想要的新类型,而不是间接定义它的降低形式。 我想你可以为此制作一个类似的Known class。

class KnownFoo f where witness :: f
instance (KnownNat a, KnownNat b) => KnownFoo (FooC a b) where witness = FooR

withKnownFoo :: forall f a b r. (KnownFoo f, f ~ FooC a b) => ((KnownNat (GetA f), KnownNat (GetB f)) => r) -> r
withKnownFoo = withKnowledge (witness @f)

不过,它似乎并不是很有用。 任何时候你可以写withKnownFoo x ,你已经在 scope 中有合适的KnownNat实例来写x并满足它的约束。

暂无
暂无

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

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