У меня есть куча сложных функций уровня типа, оценивающих на такие вещи, как:Infer ограничения семейств типа с ограничениями аргументов
(If (EqNat n 2)
1
(If (EqNat n 1)
2
(If (EqNat n 0) 3 0)))
Теперь, очевидно, в данном случае это выражение является KnownNat
. Больше в целом мы можем сказать:
forall (c :: * -> Constraint) (p :: Bool) a b .
(c a, c b) => c (If p a b)
Есть ли способ, чтобы научить GHC вывести это?
Edit: @chi отметил, что в некоторых случаях это разрешимо GADTs но мой частный случай это один:
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 должен иметь возможность заключить, что forall n . KnownNat n => KnownNat (NestedIfs n)
от общий вывод Я упоминал выше.
Мы должны 'FORALL (р :: Bool). Либо (p: ~: True) (p: ~: False) 'для этого. Я не думаю, что можно добиться этого без единого аргумента для 'p :: Bool'. – chi
Не могли бы вы рассказать об этом? 1) Какие другие типы обитают в типе 'Bool', 2) Если' Либо (p: ~: True) (p: ~: False) 'были терминалом типа Bool, это действительно помогло бы нам на техническом уровне помогая GHC автоматически выводить то, о чем я просил? – fakedrake
Кстати, возможно, примите во внимание [этот вопрос я задал на днях] (http://stackoverflow.com/questions/42240533/infer-constraints-for-both-if-and-else-of-type-equality) – fakedrake