当前位置: 首页 > 知识库问答 >
问题:

从参数约束推断类型族的约束

楚俊迈
2023-03-14

我有一系列复杂的类型级别函数,它们的计算结果如下:

(If (EqNat n 2)
  1
  (If (EqNat n 1)
    2
    (If (EqNat n 0) 3 0)))

显然,在这种情况下,这个表达式是一个KnonNat。更一般地说,我们可以说:

forall (c :: * -> Constraint) (p :: Bool) a b .
(c a, c b) => c (If p a b)

有没有办法教GHC推断这一点?

编辑:@chi指出,在某些情况下,GADT可以解决这一问题,但我的特殊情况是:

module M1 (C(..)) where

type familiy NestedIfs (n :: Nat) :: Nat
type NestedIfs n = <<complex nested ifs like the above that evals to literals>>

class C a (n :: Nat) where
  f :: KnownNat n => a -> NestedIfs n -> Bool

然后

module M2 () where
import M1

instance C Int n where
    f = ...require that KnownNat (NestedIfs n)...

NestedIfs不能被M2访问,但是也许GHC应该能够推断出for all n.已知n=


共有1个答案

衡安晏
2023-03-14

这个问题并不难,但不太合适。您希望返回类型为c(如果p a b)::Constraint的值是多少?你可能想问的是,如何填写这篇文章的正文

bisect :: forall b c x y. SingI b => Proxy b -> (c x, c y) :- c (If b x y)

正如评论中所指出的,我强迫c成为一个单身汉,这样我就可以得到中的任意一个(c:~:True)(c:~:False)(您可以将我的SingI约束解读为强制执行c::Bool必须是TrueFalse,不幸的是,在类型级别上,这不是一个微不足道的请求,因为Any也有kindBool)。:-来自约束包。这是一种表示约束(a,b)意味着约束(如果c a b)。这正是表达你的要求的方式——你想要一个证据,证明在给定cxcy的情况下,c(如果bxy)也会成立。

填充函数体实际上只需要很少的代码

{-# LANGUAGE DataKinds, TypeFamilies, ConstraintKinds, TypeOperators, RankNTypes,
    ScopedTypeVariables, PolyKinds #-}

import Data.Constraint
import Data.Singletons.Prelude hiding ((:-))

bisect :: forall b c x y. (SingI b) => Proxy b -> (c x, c y) :- c (If b x y)
bisect _ = unmapDict $ case sing :: Sing b of
                         STrue -> mapDict weaken1
                         SFalse -> mapDict weaken2
 类似资料:
  • 本文向大家介绍TypeScript 类型参数作为约束,包括了TypeScript 类型参数作为约束的使用技巧和注意事项,需要的朋友参考一下 示例 使用TypeScript 1.8,类型参数约束可以从同一类型参数列表中引用类型参数。以前这是一个错误。            

  • 销关节 cpPinJoint *cpPinJointAlloc(void) cpPinJoint *cpPinJointInit(cpPinJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2) cpConstraint *cpPinJointNew(cpBody *a, cpBody *b, cpVect anchr1,

  • 泛型的类型约束 swapTwoValues(_:_:)函数和Stack类型可以用于任意类型. 但是, 有时在用于泛型函数的类型和泛型类型上, 强制其遵循特定的类型约束很有用. 类型约束指出一个类型形式参数必须继承自特定类, 或者遵循一个特定的协议、组合协议. 例如, Swift的Dictionary类型在可以用于字典中键的类型上设置了一个限制. 如字典中描述的一样,字典键的类型必须是可哈希的. 也

  • 我定义了一个自定义GADT,其中类型构造函数对类型变量有一个类型类约束,如下所示: 我假设我不必提到约束,因为它是在GADT定义中声明的。我唯一能想到的部分原因是GADT在函数中的位置。我对此不太了解,但据我所知,在中处于正位置,在中处于负位置。 我什么时候必须明确地提到类型类约束,什么时候GHC自己根据GADTs类型构造函数上的约束来解决它?

  • 假设我有一个类模板,

  • 这将使约束在范围内,为提供额外的参数。这里我的意图是包含一些(隐藏的)具体类型,它应该用作多态函数GHC compulins的具体类型: 我的用例的假设是1。同时计算和2。隐藏类型的值涉及(至少部分)第一个元组元素的计算。这意味着我不想在中调用两次(一次是获取,一次是使用该类型绑定第一个元组元素)。在存在约束的情况下,是否有某种方法使的定义成为可能?