Haskell 为什么有些函数调用在没有类型应用程序的情况下无法工作?
我很难理解类型应用程序是如何工作的。当调用Haskell 为什么有些函数调用在没有类型应用程序的情况下无法工作?,haskell,Haskell,我很难理解类型应用程序是如何工作的。当调用knockable或opened中的sing将无法在没有类型应用程序的情况下进行类型检查时,为什么在没有类型应用程序的情况下可以使用refueterefuteknockable中的sing refuteRefuteKnockable :: SingI s => Refuted (Refuted (Knockable s)) -> Knockable s refuteRefuteKnockable rrK = case isKnock
knockable或opened
中的sing
将无法在没有类型应用程序的情况下进行类型检查时,为什么在没有类型应用程序的情况下可以使用refueterefuteknockable
中的sing
refuteRefuteKnockable :: SingI s => Refuted (Refuted (Knockable s)) -> Knockable s
refuteRefuteKnockable rrK =
case isKnockable $ sing of
Proved k -> k
Disproved rK -> absurd $ rrK rK
knockableOrOpened :: forall s. SingI s => Or Knockable ((:~:) Opened) s
knockableOrOpened =
case sing @s of
SOpened -> OrRight $ Refl
SClosed -> OrLeft KnockClosed
SLocked -> OrLeft KnockLocked
我从以下代码库工作:类型推断是原因。此类型包含
s
refuteRefuteKnockable :: SingI s => Refuted (Refuted (Knockable s)) -> Knockable s
^^^^^^^^^^^
那么这个
refuteRefuteKnockable rrK =
case isKnockable $ sing of
Proved k -> k
^^^
必须具有类型可敲击的s
。因此,推断出证明的k
的类型,可能也包含s
。这与isKnockable$sing
的类型相同,从中我们推断出应该应用于sing
的类型(利用isKnockable
的签名)。GHC为我们做了所有这些
在后一个例子中,我们不能执行相同的推理
case sing of
SOpened -> OrRight $ Refl
SClosed -> OrLeft KnockClosed
SLocked -> OrLeft KnockLocked
是不明确的,因为即使三个分支必须返回一个已知类型,我们仍然可以调用另一个类型上的sing
,然后s
并进行所有类型检查。由于没有唯一的s
,因此推理无法工作
注意,上面我不得不猜测一些事情。如果你分享你的类型定义,我们会更准确。(即,sopend
定义在哪里?关于可敲的
等呢?)