Ich habe eine Reihe von komplizierten Art Level-Funktionen, die Dinge wie bewerten:Infer Einschränkungen des Typs Familien von Zwängen der Argumente
(If (EqNat n 2)
1
(If (EqNat n 1)
2
(If (EqNat n 0) 3 0)))
Jetzt offensichtlich in diesem Fall ist dieser Ausdruck ein KnownNat
. Mehr im Allgemeinen können wir sagen:
forall (c :: * -> Constraint) (p :: Bool) a b .
(c a, c b) => c (If p a b)
Gibt es eine Möglichkeit GHC zu lehren, diese zu schließen?
Edit: @chi darauf hingewiesen, dass in einigen Fällen diese mit GADTs auflösbar ist aber mein Fall ist diese:
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
und dann
module M2() where
import M1
instance C Int n where
f = ...require that KnownNat (NestedIfs n)...
NestedIfs
nicht zugänglich M2
ist aber vielleicht sollte GHC in der Lage sein, , dass forall n . KnownNat n => KnownNat (NestedIfs n)
aus der allgemeinen Schlussfolgerung, die ich oben erwähne.
Wir brauchen 'forall (p :: Bool). Entweder (p: ~: True) (p: ~: False) 'dafür. Ich denke nicht, dass man das ohne Singleton-Argument für "p :: Bool" erreichen kann. – chi
Könnten Sie das näher ausführen? 1) Welche anderen Arten bewohnen die 'Bool'-Art, 2) Wenn 'Entweder (p: ~: True) (p: ~: False)' ein Ende der Bool-Art war, würde uns das auf der technischen Ebene tatsächlich helfen Hilft GHC, automatisch zu folgern, wonach ich gefragt habe? – fakedrake
Nebenbei bemerkt vielleicht [diese Frage fragte ich neulich] (http://stackoverflow.com/questions/42240533/infer-constraints-for-both-if-and-else-of-type-equality) – fakedrake