Я читал статью Джереми Гиббонса о программировании оригами. и я застрял на упражнении 3.7, в котором читателю предлагается доказать закон слияния для развертывания списка:
unfoldL p f g . h = unfoldL p' f' g'
if
p . h = p' f . h = f' g . h = h . g'
Функция unfoldL
, развернутая для списков, определяется следующим образом:
unfoldL :: (b -> Bool) -> (b -> a) -> (b -> b) -> b -> List a
unfoldL p f g b = if p b then Nil else Cons (f b) (unfoldL p f g (g b))
Вот моя текущая попытка доказательства:
(unfoldL p f g . h) b
= { composition }
unfoldL p f g (h b)
= { unfoldL }
if p (h b) then Nil else Cons (f (h b)) (unfoldL p f g (g (h b)))
= { composition }
if (p . h) b then Nil else Cons ((f . h) b) (unfoldL p f g ((g . h) b))
= { assumptions }
if p' b then Nil else Cons (f' b) (unfoldL p f g ((h . g') b))
= { composition }
if p' b then Nil else Cons (f' b) ((unfoldL p f g . h) (g' b))
= { ??? }
if p' b then Nil else Cons (f' b) (unfoldL p' f' g' (g' b))
= { unFoldL }
unFoldL p' f' g'
Я не уверен, как оправдать шаг, отмеченный ???
. Вероятно, мне следует использовать какую-то индукцию по применению функции на b
? Связанный с этим вопрос: какие есть хорошие ресурсы, которые объясняют и мотивируют различные методы индукции, такие как структурная индукция?