Haskell 我能让GHC推断出通过GADT模式匹配的约束吗?
我想让GHC推断出通过GADT模式匹配的约束。例如,假设我有两个表达式,每个表达式都有一个推断约束:Haskell 我能让GHC推断出通过GADT模式匹配的约束吗?,haskell,ghc,type-inference,type-level-computation,Haskell,Ghc,Type Inference,Type Level Computation,我想让GHC推断出通过GADT模式匹配的约束。例如,假设我有两个表达式,每个表达式都有一个推断约束: f::=>a g::。=>a (在我的用例中,这些推断出的约束可能很大,因此手工写出它们是不可行的。) 然后假设我想根据布尔条件使用f或g。天真地说,我可以这样做: h1::=>Bool->a h1 c=如果为c,则为f,否则为g 假设我调用fct\u f的推断约束和gct\u g的推断约束,那么GHC将推断h1的约束(ct\u f,ct\u g) 问题是,这是一种限制过度的类型:如果布尔值
f::=>a
g::。=>a
(在我的用例中,这些推断出的约束可能很大,因此手工写出它们是不可行的。)
然后假设我想根据布尔条件使用f
或g
。天真地说,我可以这样做:
h1::=>Bool->a
h1 c=如果为c,则为f,否则为g
假设我调用f
ct\u f的推断约束和g
ct\u g
的推断约束,那么GHC将推断h1
的约束(ct\u f,ct\u g)
问题是,这是一种限制过度的类型:如果布尔值是True
,我不需要ct\u g
,反之,如果它是False
,我不需要ct\u f
。因此,我尝试使用标准机制来实现这种依赖约束:
datasbool(c::Bool)其中
SFalse::SBool False
STrue::SBool True
h2::\=>SBool bool->a
h2=\case
STrue->f
SFalse->g
然而,这不起作用,因为GHC的部分类型签名算法拒绝通过GADT模式匹配来浮动约束。相反,我可以尝试明确告诉GHC该做什么:
ifC::对于所有ct\t ct\f布尔x。SBool bool->(ct\u t=>x)->(ct\u f=>x)->(如果bool ct\u t ct\u f=>x)
国际金融公司股票指数a uA=a
ifC SFalse uB=b
h3:::=>SBool bool->a
h3 c=ifC c f g
这种方法也失败了,这一次是因为GHC认为ifC
的类型签名不明确,即GHC需要用户明确传递如下约束
h4 c=ifC@ct\u f@ct\u g
不幸的是,我不能明确地传递这些约束:我要求GHC推断它们,而没有办法引用它们。例如,可以尝试将其纳入范围,如下所示:
h5::=>SBool bool->a
h5 c=
让
f::_ct_f=>a
f'=f
g::_ct_g=>a
g'=g
在里面
如果"你来","你来","你来",
但这是行不通的,因为GHC不支持命名通配符作为额外约束的替代(即使它支持,它们也不能正确地作用域)
是否有其他方法可以让GHC推断:
h::(如果bool ct\u f ct\u g)=>a
我使用impindicativetypes
稍微改进了代码
type family GetBool a where
GetBool (SBool True) = True
GetBool (SBool False) = False
data TF (a :: Constraint) x = TF x
class SIf a pt pf x where
ifC' :: a -> TF pt x -> TF pf x -> (If (GetBool a) pt pf => x)
instance ((t => x) ~ (f => x)) => SIf (SBool True) t f x where
ifC' _ (TF t) _ = t
instance ((t => x) ~ (f => x)) => SIf (SBool False) t f x where
ifC' _ _ (TF f) = f
h3' :: _ => SBool bool -> a
h3' c = ifC' c f g
它的作用是给它一个Num
实例
*Main> :t h3' 3
h3' 3
:: (If (GetBool (SBool bool)) pt pf, SIf (SBool bool) pt pf a,
Num (SBool bool)) =>
a
让x=h3'f
目前也可以使用,但并不完美。我想我们所做的是黑魔法…如果的定义来自哪里?“我没有办法提及它们”你的意思是你不想在设计时明确提及这些约束,还是存在其他障碍?我认为这里的核心问题是:约束之间从来没有统一过。这对于任何试图这样做的人来说似乎都是相当糟糕的。对于一个发人深省的问题来说+1,但老实说,我认为整个方法是注定要失败的。当然,打字孔很方便,但我认为过分依赖它们并不明智。我认为这并不能回答问题。目标是使h3'
类型中的t
和f
分别精确地作为f
和g
的约束条件。GHC在您的示例中没有发现这个等式。嗯,但是在这个示例中,GHC为f
和g
推断出约束()
。如果您将其更改为f=3
(因此为f
推断的约束为Num a
),则h3'
会导致错误“无法推断(Num a)因使用f而产生”。在更好的想法弹出之前,我暂时保留它(如果弹出,则删除它)。