У нас были прекрасные ответы, но как преступник, я думал, что уйду некоторые замечания.
Да, есть несколько эквивалентных представлений этих лемм. Презентация, которую я использую, является одной из них, и выбор во многом прагматичный. В эти дни (в более позднем кодовую), я иду так далеко, чтобы определить
-- Holds :: Constraint -> *
type Holds c = forall t . (c => t) -> t
Это пример типа выпрямитель: он абстрагирует над тем, что она обеспечивает (мотив элиминации) и он требует, чтобы вы построили ноль или более методов (один здесь) для достижения мотивов при более конкретных обстоятельствах. Способ читать это назад. Это говорит
Если у вас есть проблемы (населять любой тип мотива t
), и никто не может помочь, может быть, вы можете достичь прогресса, если предположить, ограничение c
в вашем методе.
Учитывая, что язык ограничений допускает конъюнкции (ака кортежей), мы получаем средства для написания лемм вида
lemma :: forall x1 .. xn. (p1[x1 .. xn],.. pm[x1 .. xn]) -- premises
=> t1[x1 .. xn] -> .. tl[x1 .. xn] -- targets
-> Holds (c1[x1 .. xn],.. ck[x1 .. xn]) -- conclusions
и это может быть даже, что некоторые ограничения, помещение p
или заключение c
, имеет вид уравнения
l[x1 .. xn] ~ r[x1 .. cn]
Теперь, чтобы развернуть такую lemma
, рассмотрит проблему наполнения отверстия
_ :: Problem
Уточнить это _
устранением lemma
, с указанием целей. Момент исходит из проблемы. Метод (единственное в случае Holds
) остается открытым.
lemma target1 .. targetl $ _
и дырка метода не будут изменены типа
_ :: Problem
но GHC будет знать кучу больше вещей, и, таким образом, более склонно верить ваше решение.
Иногда существует выбор ограничения по сравнению с данными для того, чтобы сделать предпосылку (ограничение) и цель (данные).Я предпочитаю выбирать их, чтобы избежать двусмысленности (Саймону нравится угадывать , но иногда ему нужен намек), а для облегчения доказательство по индукции, что намного проще по целям (часто это синглтоны для данных типа уровня), чем в помещениях.
Что касается развертывания, для уравнений, можно, конечно, переключиться на типе данных презентацию и вспыхивает анализ тематического
case dataLemma target1 .. targetl of Refl -> method
и в самом деле, если вы вооружить себя с Dict
экзистенциального
data Dict (c :: Constraint) :: * where
Dict :: c => Dict c
вы можете сделать пучок сразу
case multiLemma blah blah blah of (Refl, Dict, Dict, Refl) -> method
но форма выталкивателя более компактна и читаема , когда существует не более одного метода. Действительно, мы можем цепи несколько лемм без скольжения либо вправо
lemma1 .. $
...
lemmaj .. $
method
Если у вас есть такой выпрямитель с двумя или более случаев, я думаю, что это часто лучше, чтобы обернуть его как GADT, так что сайты использования услужливо маркировать каждый case с меткой конструктора.
Во всяком случае, да, дело в том, чтобы выбрать презентацию фактов, которые наиболее компактно позволяют нам расширить сферу применения механизмов решения ограничений ограничений GHC, чтобы больше вещей было просто typechecks. Если вы в отряде с Саймоном, это часто хорошая стратегия, чтобы объяснить себя Димитрию по соседству.
Кто-то светит сигнал @pigworker. –
@ReinHenrichs Я думаю, вам нужно проецировать 'Π' на ночное небо, чтобы привлечь его внимание. –
Хотя этот вопрос по теме из-за участия Haskell, он имеет сильную теоретико-теоретическую направленность, поэтому он может иметь лучший шанс на [cs.se] (или, возможно, даже [cstheory.se]). Не переставляйте; вы можете запросить миграцию своего вопроса, отметив его. – Gilles