LINUX.ORG.RU

Racket, объясните про lambda

 , ,


2

3

Учу потихоньку Racket. Раньше был такой код для вычисления дискриминанта:

(define (дискриминант a b c)
  (define bandb (* b b))
  (define fac ( * 4 a c))
  (- bandb fac))

И сам код для решения квадратного уравнение:

(define (квадратное_уравнение a b c)
  (define d (дискриминант a b c))
  (cond
    [(> 0 d)
     (print "Квадратное уравнение не имеет корней""")]
    [(equal? d 0)
     (/ ( - b) (* 2 a))]
    [(> d 0)
     (print "D:""")
     (println d)
     (print "X1"":")
     (println ( / ( + (- b) (sqrt d)) ( * 2 a)))
     (print"\n""X2:")
     (/ ( - ( - b) ( sqrt d)) ( * 2 a))]))
     
     
    (квадратное_уравнение -1 2 3) ;выводит 16 как и полагается


Теперь решил попробовать написать такую же решалку, только с использованием lambda:
#lang racket
(define (напечатать text)
  (println text))
(define two.x
  (lambda (a b c d)
    (( / ( + (- b) (sqrt d)) ( * 2 a)))
    (/ ( - ( - b) ( sqrt d)) ( * 2 a))))
(define x.one
  (lambda (a b)
    (/ ( - b) ( * 2 a))))

(define дискриминант
  (lambda (a b c)
    (let ([f 4])
      (define b.sqrt (* b b))
      (define four.a.c ( * f a c))
      (- b.sqrt four.a.c))))
(define квадратное_уравнение
  (lambda (a b c)
    (let ([D (дискриминант a b c)])
      (cond
        [(> 0 D)
         (напечатать "Квадратное уравнение не имеет корней")]
        [(equal? D 0)
         (x.one a b)]
        [( > D 0)
         (two.x a b c D)]))))


Но получаю данную ошибку:
. . application: not a procedure;
 expected a procedure that can be applied to arguments
  given: -1
  arguments...: [none]
Поясните мне, что я делаю не так?

P.S Дискриминант вычисляется

P.S.S gist кода для решения уравнений: url

★★

Последнее исправление: playX (всего исправлений: 1)

Поясните мне, что я делаю не так?

Судя по ошибке в какой-то форме у тебя первым аргументом вместо функции получилось число -1.

Судя по коду, это где-то здесь: (( / ( + (- b) (sqrt d)) ( * 2 a))).

Судя по предыдущему примеру, ты забыл после первой скобки написать «напечатать».

monk ★★★★★
()
Ответ на: комментарий от monk

Когда я вызываю (квадратное_уравнение -1 2 3) должен сработать этот кусок кода:

[( > D 0)
  (two.x a b c D)]))))


И там как бы передается -1 как число, тогда я не понимаю что тут не так? Ведь -1 и должно быть числом что бы уравнение решить, разве нет?
Я даже делал так:
(define two.x
  (lambda (a b c d)
    (println (( / ( + (- b) (sqrt d)) ( * 2 a))))
    (println (/ ( - ( - b) ( sqrt d)) ( * 2 a)))))
Но как не трудно догадаться не сработало

playX ★★
() автор топика
Ответ на: комментарий от playX

Я даже делал так:

Теперь у тебя невыполнимое выражение — аргумент первого println

Попробуй подумать чему равно (( / ( + (- b) (sqrt d)) ( * 2 a))) для каких нибудь значений переменных (например, все равно единицам).

monk ★★★★★
()
Ответ на: комментарий от monk

Убрал одну скобку после первого println, вроде как завелось, но если дискриминант равен нулю, не хочет его считать, думаю это уже постараюсь сам эту проблему решить:) (какие же скобочки беспощадные)

playX ★★
() автор топика
Последнее исправление: playX (всего исправлений: 1)
Ответ на: комментарий от playX

но если дискриминант равен нулю, не хочет его считать

Думаю, дело в том, что в той ветке печати результата нет.

какие же скобочки беспощадные

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

Зато с ними можно писать так:

(define res
  (lambda (a b c)
    (println
      ((lambda (d calc1 calc2)
         (cond
           [(> 0 d) "нет корней"]
           [(= 0 d) (calc1)]
           [else (list (calc2 + d)
                       (calc2 - d))]))
       (- (* b b) (* 4 a c))
       (lambda () (/ (- b) (* 2 a)))
       (lambda (op d) (/ (op (- b) (sqrt d)) (* 2 a)))))))

Здесь у аргумента println первый аргумент (lambda (d calc1 calc2) ...). Значит, остальные аргументы будут вычислены и переданы в неё. В d попадает вычисление дискриминанта, а в calc1 и calc2 ещё две лямбды, то есть функции. Таким образом можно писать без повторений и очень лаконично и понятно.

monk ★★★★★
()

за [(> 0 D) (напечатать «Квадратное уравнение не имеет корней»)] нюбов лишают печенек, а про-двинутых разжалуют в нюбы :-)

так не делают ну нигде вообще - вы определили сущность «решение КВУР», так и отдавайте полное решение. А нужны или нет мнимые корни - пусть решает верхний уровень. Там кстати и занимайтесь вводом-выводом

ps/ вообще в функциональщине логично отдавать далее/наверх лямбды, чем готовые числа. Получили из 3-х чисел две конст.функции - всё, квадратное уравнение решено.

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

так не делают ну нигде вообще - вы определили сущность «решение КВУР» так и отдавайте полное решение. А нужны или нет мнимые корни - пусть решает верхний уровень. Там кстати и занимайтесь вводом-выводом

Зависит от постановки задачи. Если задача «написать функцию, которая печатает реальные корни квадратного уравнения или фразу «Квадратное уравнение не имеет корней», если таковые отсутствуют», то она решена верно.

monk ★★★★★
()
Ответ на: комментарий от MKuznetsov

вообще в функциональщине логично отдавать далее/наверх лямбды, чем готовые числа

В смысле? Вместо 3 возвращать (lambda () 3)? Зачем?

Не путай функциональщину и ленивость. Не каждый функциональный язык является ленивым.

monk ★★★★★
()
Ответ на: комментарий от MKuznetsov

Человек явно учится - и должен уметь раскладывать сложные функции на композиции простых.

Это приходит с опытом. А если раскладывать всё что попало под руку, то потом появляется алгоритм Life на 120 функций. Всё должно быть в меру.

Я этот вопрос уже поднимал в Повторное использование кода

monk ★★★★★
()
Ответ на: комментарий от MKuznetsov

должен уметь раскладывать сложные функции на композиции простых.

Так он раскладывает: дискриминант, two.x, x.one. Какое отношение имеет заворачивание результата в функцию к композиции?

monk ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.