скажем, у меня есть
data Fruit = Apple | Banana | Grape | Orange | Lemon | {- many others -}
и предикат для этого типа,
data WineStock : Fruit -> Type where
CanonicalWine : WineStock Grape
CiderIsWineToo : WineStock Apple
что не выполняется для Banana
, Orange
, Lemon
и других.
можно сказать, что это определяет WineStock
как предикат Fruit
; WineStock Grape
является истинным (поскольку мы можем построить значение/доказательство этого типа: CanonicalWine
), так же как и WineStock Apple
, но WineStock Banana
является ложным, так как этот тип не содержит никаких ценности/доказательства.
Тогда как я могу эффективно использовать Not (WineStock Banana)
, Not (WineStock Lemon)
и т. д.? Кажется, что для каждого конструктора Fruit
, кроме Grape
и Apple
, я не могу не закодировать случай, разделенный на WineStock
, где-то полный impossible
s:
instance Uninhabited (WineStock Banana) where
uninhabited CanonicalWine impossible
uninhabited CiderIsWineToo impossible
instance Uninhabited (WineStock Lemon) where
uninhabited CanonicalWine impossible
uninhabited CiderIsWineToo impossible
instance Uninhabited (WineStock Orange) where
uninhabited CanonicalWine impossible
uninhabited CiderIsWineToo impossible
Обратите внимание, что:
- код повторяется,
- LoC взорвется, когда определение предиката разрастется, получив больше конструкторов. Только представьте доказательство
Not (Sweet Lemon)
, предполагая, что в определенииFruit
есть много приятных альтернатив.
Таким образом, этот способ кажется не совсем удовлетворительным, почти непрактичным.
Есть ли более элегантные подходы?
data WineFruit = Grape | Apple
и другие фруктыdata Fruit = WineFruit WineFruit | Banana | Orange | Lemon
. - person Benjamin Hodgson♦   schedule 03.02.2016PieFruit
,SaladFruit
,WeaponFruit
и т. д. - person dfeuer   schedule 15.02.2016WineStock
? Разве вы не можете просто определитьisWineStock
как функцию уровня значения и использовать ее в доказательствах, где это уместно? - person sclv   schedule 19.03.2016