Я пытаюсь преобразовать церковную кодировку в цифры. Я определил свое собственное определение Lambda следующим образом:
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
То, как я понимаю лямбда-кодирование для трех чисел, таково:
0: \s. \z. z
1: \s. \z. s z
2: \s. \z. s (s z)
Итак, я предполагаю, что моя логика верна, но мне трудно понять, как будет происходить обратное преобразование. Я новичок в Haskell, поэтому любая помощь в объяснении того, что я могу делать неправильно, очень ценится.