2016-06-04 15 views
1

meine Aufgabe ist es, neue Funktion namens sqrt + zu meinem Schläger Sprache hinzuzufügen.Hinzufügen von sqrt-Funktion zu der Sprache von Racket pl 03

Die Rückgabe-Liste der Funktion sqrt + mit der Wurzel der Nummer und der negativen Wurzel von ihm.

Der Weg zum sqrt + Funktion aufzurufen i von Sqrt Syntax:

#lang pl 03 

#| BNF for the MUWAE language: 
    <MUWAE> ::= <num> 
      | { + <MUWAE> <MUWAE> } 
      | { - <MUWAE> <MUWAE> } 
      | { * <MUWAE> <MUWAE> } 
      | {/<MUWAE> <MUWAE> } 
      | { Sqrt <MUWAE>  } 
      | { with { <id> <WAE> } <MUWAE> } 
      | <id> 
|# 

;; MUWAE abstract syntax trees 
(define-type MUWAE 
    [Num Number] 
    [Add MUWAE MUWAE] 
    [Sub MUWAE MUWAE] 
    [Mul MUWAE MUWAE] 
    [Div MUWAE MUWAE] 
    [Sqrt MUWAEE] 
    [Id Symbol] 
    [With Symbol MUWAE MUWAE]) 

(: parse-sexpr : Sexpr -> MUWAE) 
;; to convert s-expressions into MUWAEs 
(define (parse-sexpr sexpr) 
    (match sexpr 
    [(number: n) (Num n)] 
    [(symbol: name) (Id name)] 
    [(cons 'with more) 
    (match sexpr 
     [(list 'with (list (symbol: name) named) body) 
     (With name (parse-sexpr named) (parse-sexpr body))] 
     [else (error 'parse-sexpr "bad `with' syntax in ~s" sexpr)])] 
    [(list '+ lhs rhs) (Add (parse-sexpr lhs) (parse-sexpr rhs))] 
    [(list '- lhs rhs) (Sub (parse-sexpr lhs) (parse-sexpr rhs))] 
    [(list '* lhs rhs) (Mul (parse-sexpr lhs) (parse-sexpr rhs))] 
    [(list '/ lhs rhs) (Div (parse-sexpr lhs) (parse-sexpr rhs))] 
    [(list 'Sqrt s) (sqrt+ (parse-sexpr s))] 
    [else (error 'parse-sexpr "bad syntax in ~s" sexpr)])) 

(: parse : String -> MUWAE) 
;; parses a string containing a MUWAE expression to a MUWAE AST 
(define (parse str) 
    (parse-sexpr (string->sexpr str))) 

#| Formal specs for `subst': 
    (`N' is a <num>, `E1', `E2' are <MUWAE>s, `x' is some <id>, 
    `y' is a *different* <id>) 
     N[v/x]    = N 
     {+ E1 E2}[v/x]  = {+ E1[v/x] E2[v/x]} 
     {- E1 E2}[v/x]  = {- E1[v/x] E2[v/x]} 
     {* E1 E2}[v/x]  = {* E1[v/x] E2[v/x]} 
     {/ E1 E2}[v/x]  = {/ E1[v/x] E2[v/x]} 
     y[v/x]    = y 
     x[v/x]    = v 
     {with {y E1} E2}[v/x] = {with {y E1[v/x]} E2[v/x]} 
     {with {x E1} E2}[v/x] = {with {x E1[v/x]} E2} 
|# 

(: subst : MUWAE Symbol MUWAE -> MUWAE) 
;; substitutes the second argument with the third argument in the 
;; first argument, as per the rules of substitution; the resulting 
;; expression contains no free instances of the second argument 
(define (subst expr from to) 
    (cases expr 
    [(Num n) expr] 
    [(Add l r) (Add (subst l from to) (subst r from to))] 
    [(Sub l r) (Sub (subst l from to) (subst r from to))] 
    [(Mul l r) (Mul (subst l from to) (subst r from to))] 
    [(Div l r) (Div (subst l from to) (subst r from to))] 
    [(Sqrt s) (sqrt+ (subst s from to))] 
    [(Id name) (if (eq? name from) to expr)] 
    [(With bound-id named-expr bound-body) 
    (With bound-id 
      (subst named-expr from to) 
      (if (eq? bound-id from) 
      bound-body 
      (subst bound-body from to)))])) 

#| Formal specs for `eval': 
    eval(N)   = N 
    eval({+ E1 E2}) = eval(E1) + eval(E2) 
    eval({- E1 E2}) = eval(E1) - eval(E2) 
    eval({* E1 E2}) = eval(E1) * eval(E2) 
    eval({/ E1 E2}) = eval(E1)/eval(E2) 
    eval(id)  = error! 
    eval({with {x E1} E2}) = eval(E2[eval(E1)/x]) 
|# 

(: eval : MUWAE -> Number) 
;; evaluates MUWAE expressions by reducing them to numbers 
(define (eval expr) 
    (cases expr 
    [(Num n) n] 
    [(Add l r) (+ (eval l) (eval r))] 
    [(Sub l r) (- (eval l) (eval r))] 
    [(Mul l r) (* (eval l) (eval r))] 
    [(Div l r) (/ (eval l) (eval r))] 
    [(Sqrt s) (sqrt+ (eval s))] 
    [(With bound-id named-expr bound-body) 
    (eval (subst bound-body 
        bound-id 
        (Num (eval named-expr))))] 
    [(Id name) (error 'eval "free identifier: ~s" name)])) 

(: run : String -> Number) 
;; evaluate a MUWAE program contained in a string 
(define (run str) 
    (eval (parse str))) 

(: sqrt+ : (Listof Number) -> (Listof Number)) 
;; a version of `sqrt' that takes a list of numbers, and return a list 

;; with twice the elements, holding the two roots of each of the inputs; 

;; throws an error if any input is negative. 
(define (sqrt+ ns) 
(cond [(null? ns) 0] 
[(< (first ns) 0) (error 'ns "`sqrt' requires a nonnegative input ~s")] 
[else (sqrt ns (* (sqrt ns) -1))])) 

aber wenn ich versuche, die Sprache, die ich bekommen laufen:

Fälle: fehlende Fälle für folgende Varianten: (Sqrt ...)

Was habe ich vermisst und musste ändern?

+0

Können Sie ein kleineres Beispiel mit nur der minimalen Menge an Code machen, die den Fehler verursacht? –

Antwort

1

Ohne Ihr Programm versucht:

[(Sqrt s) (sqrt+ (subst s from to))] 

in der subst Funktion scheint falsch zu sein. subst soll eine MUWAE zurückgeben. Der Rückgabetyp sqrt+ ist jedoch eine Liste von Nummern. Auch

,

[(Sqrt s) (sqrt+ (eval s))] 

in der eval Funktion scheint falsch zu sein, weil wieder, eval sollte eine Zahl zurück. Der Rückgabetyp sqrt+ ist jedoch eine Liste von Nummern. In ähnlicher Weise soll der Typ (eval s) eine Nummer sein, aber sqrt+ verbraucht eine Liste von Zahlen.

Schließlich glaube ich auch, dass Ihre Implementierung von sqrt+ ist auch falsch. Insbesondere macht es keinen Sinn, [else (sqrt ns (* (sqrt ns) -1))] zu schreiben, weil sqrt eine Nummer verbraucht ...

+0

ich neue kurze Frage erstellen: http://StackOverflow.com/Questions/37645573/Create-Sqrt-Function-in-Racket nur um herauszufinden, warum die sqrt + nicht funktioniert –