Найдите функции Хаскелла f, g такие, что f g = f . г
Изучая Haskell, я столкнулся с проблемой найти две функции f
а также g
такой, что f g
а также f . g
эквивалентны (и всего, поэтому такие вещи, как f = undefined
или же f = (.) f
не в счет). Данное решение таково, что f
а также g
оба равны \x -> x . x
(или же join (.)
).
(Я отмечаю, что это не специфично для Хаскеля; это можно выразить в чистой комбинаторной логике как "найти f
а также g
такой, что f g = B f g
", и данное решение будет затем переводить в f = g = W B
.)
Я понимаю, почему данное решение работает, когда я расширяю его, но я не понимаю, как вы могли бы его найти, если бы вы его еще не знали. Вот как далеко я могу получить:
f g = f . g
(дано)f g z = (f . g) z
(Эта-расширение обеих сторон)f g z = f (g z)
(упростить RHS)
И я не знаю, как действовать дальше. Что я буду делать дальше, пытаясь найти решение?
1 ответ
Я обнаружил, что можно найти семейство решений, рассмотрев вычисление церковных чисел. В церковном кодировании умножение выполняется путем составления церковных чисел, а возведение в степень - путем применения базы к показателю степени. Таким образом, если f
Церковная кодировка некоторого числа x
, а также g
Церковная кодировка некоторого числа y
, затем f g = f . g
подразумевает y^x = x*y
, Любые неотрицательные целочисленные решения этого уравнения переводятся в решения исходной задачи. Примеры:
x=1, y=0, f=id, g=const id
x=1, y=1, f=id, g=id
x=1, y=2, f=id, g=join (.)
- поскольку
y^1 = y = 1*y
для всехy
имеет смысл, чтоf=id
работает для всех церковных цифрg
, Это действительно так, и на самом деле, как отметил Рейн Хенрикс, это верно для всехg
и это легко проверить осмотром. x=2, y=0, f=join (.), g=const id
x=2, y=2, f=join (.), g=join (.)
x=3, y=0, f=(.) <*> join (.), g=const id
- поскольку
0^x = 0 = x*0
за все позитивноеx
имеет смысл, чтоg=const id
работает для всех положительных церковных цифрf
, (Это не работает дляf=const id
Церковная цифра 0, которая имеет смысл, так как0^0
это неопределенная форма.)