Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 我能让GHC推断出通过GADT模式匹配的约束吗?_Haskell_Ghc_Type Inference_Type Level Computation - Fatal编程技术网

Haskell 我能让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) 问题是,这是一种限制过度的类型:如果布尔值

我想让GHC推断出通过GADT模式匹配的约束。例如,假设我有两个表达式,每个表达式都有一个推断约束:

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而产生”。在更好的想法弹出之前,我暂时保留它(如果弹出,则删除它)。