Я пытаюсь преобразовать кодировку церкви в цифры. Я определил свое собственное лямбда-определение следующим образом:
type Variable = String
data Lambda = Lam Variable Lambda
| App Lambda Lambda
| Var Variable
deriving (Eq, Show)
Я уже написал преобразование чисел в церковное кодирование, и оно работает так, как я ожидаю, вот как я его определил:
toNumeral :: Integer -> Lambda
toNumeral n = Lam "s" (Lam "z" (wrapWithAppS n (Var "z")))
where
wrapWithAppS :: Integer -> Lambda -> Lambda
wrapWithAppS i e
| i == 0 = e
| otherwise = wrapWithAppS (i-1) (App (Var "s") e)
Я запустил свои собственные тесты и вот выходные данные терминала при тестировании на 0, 1 и 2:
*Church> toNumeral 0
Lam "s" (Lam "z" (Var "z"))
*Church> toNumeral 1
Lam "s" (Lam "z" (App (Var "s") (Var "z")))
*Church> toNumeral 2
Lam "s" (Lam "z" (App (Var "s") (App (Var "s") (Var "z"))))
Теперь я пытаюсь сделать наоборот, и я просто не могу обернуть головувокруг аргументов, которые должны быть переданы. Вот что у меня есть:
fromNumeral :: Lambda -> Maybe Integer
fromNumeral (Lam s (Lam z (App e (Var x))))
| 0 == x = Just 0
| ...
Я пытался заменить (App e (Var x))
на (Var x)
, но я получаю эту ошибку для обоих случаев, когда пытаюсь проверить свой базовый случай преобразования церковной кодировки от 0 до Just 0:
*** Exception: Church.hs:(166,1)-(167,23): Non-exhaustive patterns in function fromNumeral
То, как я понимаю лямбда-кодировку для 3 чисел, таково:
0: \ s. \ Г. z
1: \ s. \ Г. sz
2: \ s. \ Г. s (sz)
Итак, я предполагаю, что моя логика верна, но мне трудно понять, как будет происходить обратное преобразование. Я довольно новичок в Haskell, поэтому любая помощь в объяснении того, что я могу делать неправильно, очень ценится.