Почему я получаю нотацию mcons в выводе моей пары? - PullRequest
0 голосов
/ 26 октября 2018

Я пытаюсь реализовать расширенный алгоритм Эйлера в Схеме и нахожу правильный результат, однако моя главная цель - получить решение в паре.Но я не понимаю, почему перед моей парой стоит нотация mcons.

Вот моя функция и вывод

(define ax+by=1 
  (lambda (a b)
    (if (= a 0)
        (cons 0 1)
        (let ((pair (ax+by=1 (remainder b a) a)))
          (cons (- (cdr pair)
                   (* (quotient b a) (car pair)))
                (car pair))))))

 ; > (ax+by=1 17 13)
 ; (mcons -3 4)

Мне нужен совет, чтобы получить ответ вформа (-3 4).

Ответы [ 2 ]

0 голосов
/ 27 октября 2018

Это связано с используемым языком или настройкой печати в DrRacket.Это просто, как это визуализируется .. Если вы спросите меня, что такое 5+6, и я отвечу XI, то ответ неправильный?

Обычно, если вы используете библиотеки rnrs в ракетных языках, вы видите mcons, так какэто пары стандартных схем, названные cons в этом режиме, но визуализируемые иначе, чем, например.#lang racket

0 голосов
/ 27 октября 2018
(define ax+by=1
  (lambda (a b)
    (if (= a 0)
        (list 0 1)
        (let ((pair (ax+by=1 (remainder b a) a)))
          (cons (- (cadr pair)
                   (* (quotient b a) (car pair)))
                (list (car pair)))))))
 ; > (ax+by=1 17 13)
 ; '(-3 4)

Ваша "проблема" заключалась в том, что ваша функция возвращала cons-ячейку, последний элемент которой НЕ '(). Список - это любая цепочка cons-ячеек с последним элементом как nil.

Если ваш код (cons 3 4), он возвращает (3 . 4). Или в вашей записи (это не Ракетка, не так ли? Или субдиалект Ракетки? (mcons 3 4)). Чтобы сделать его обычным списком, он должен стать (cons 3 (cons 4 '())), который точно такой же, как (list 3 4). list принимает аргументы и помещает их в '() в своей последней cons ячейке.

(define ax+by=1
  (lambda (a b)
    (if (= a 0)
        (cons 0 (cons 1 '()))
        (let ((pair (ax+by=1 (remainder b a) a)))
          (cons (- (cadr pair)
                   (* (quotient b a) (car pair)))
                (cons (car pair) '()))))))

Супер ленивое решение

Или, скажем, вы супер ленивый, и вы видите, что ваша старая функция действительно делает то, что должна - только формат вывода должен быть изменен от пары к списку.

С помощью этой функции вы можете преобразовать пару в список:

(define (pair->list p)
  (list (car p) (cdr p))) ; just list the components of pair

Затем вы можете взять свою старую функцию - без изменений - затем функцию преобразователя и обернуть вокруг нее определение функции - даже с тем же именем (однако, это действительно ПЛОХО для читабельности! - однако, интересно, что это работает в Racket ...).

(define ax+by=1
  (lambda (a b)
    ;; your old function verbatim as inner `ax+by=1`:
    (define ax+by=1 
      (lambda (a b)
        (if (= a 0)
            (cons 0 1)
            (let ((pair (ax+by=1 (remainder b a) a)))
              (cons (- (cdr pair)
                       (* (quotient b a) (car pair)))
                    (car pair))))))
    ;; the transformer function verbatim:
    (define (pair->list p)
      (list (car p) (cdr p)))
    ;; call both inner functions in combination!
    (pair->list (ax+by=1 a b)))) 
    ;; `pair->list` transforms your answer into the correct list form!

Примечательно, что в этой последней версии в последнем вызове функции ax+by=1 интерпретатор / компилятор «знает», что подразумевается внутренняя функция, а не внешняя функция (иначе внешняя функция будет вызывать себя снова и снова передача заданных аргументов в бесконечный цикл). Это возможно, потому что внутренняя привязка имени функции «затеняет» внешнюю привязку имени функции.

Однако я бы посчитал это действительно плохим стилем, потому что читатель-человек может очень запутаться с одинаковым именем между внутренней и внешней функцией. Тем не менее, мне было интересно найти способ не изменять существующий код и просто добавлять что-то, чтобы заставить его работать, и даже использовать намеченное старое имя - так, чтобы результат был точно желаемым результатом.

Но, безусловно, первые решения, которые я дал, лучше - нет возможности неправильно понять код и запутать вещи - и напрямую составить список результатов.

...