2016-04-25 7 views
4

eine Funktion remove_option schreiben, die einen String und eine Stringliste nimmt. Rückgabe Keine, wenn die Zeichenfolge nicht in der Liste enthalten ist, sonst EINIGE xs zurück, wo xs auf die Argumentliste mit Ausnahme der Zeichenfolge identisch ist, ist nicht drin. Sie können davon ausgehen, dass die Zeichenfolge höchstens einmal in der Liste enthalten ist. Verwenden Sie same_string, das Ihnen zur Verfügung gestellt wurde, um Strings zu vergleichen. Die Probenlösung ist ungefähr 8 Zeilen lang.rechts Seite der Klausel nicht einverstanden mit der Funktion Ergebnistyp

Der Funktionstyp fn werden sollte: string * String-Liste -> string Liste option.Here meinen Code

fun same_string(s1 : string, s2 : string) = 
    s1 = s2 
fun remove_option (str: string ,str_list : string list) = 
    case str_list of 
     [] => NONE 
      | x::xs => if same_string(x,str) 
      then SOME xs 
      else x :: remove_option(str,xs) 

und der Fehlerbericht

hw2provided.sml:10.5-15.37 Error: right-hand-side of clause doesn't agree with f 
unction result type [tycon mismatch] 
    expression: _ option 
    result type: string list 
    in declaration: 
    remove_option = 
     (fn (<pat> : string,<pat> : string list) => 
      (case str_list 
       of <pat> => <exp> 
       | <pat> => <exp>)) 

uncaught exception Error 
    raised at: ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27 
      ../compiler/TopLevel/interact/evalloop.sml:44.55 
      ../compiler/TopLevel/interact/evalloop.sml:292.17-292.20 

Also, wo der Fehler ist?

Antwort

3

Seit John zeigte, wo der Fehler ist, sind hier einige zusätzliche Kommentare:

  • Da die Funktion same_string nicht eingespritzt wird, ist es überflüssig. Sie können auch = verwenden.
  • rekursive Funktionen, die ‚eine Option sind etwas schwierig zurückgeben, da Sie das Ergebnis auspacken müssen:

    fun remove_option (s1, []) = NONE 
        | remove_option (s1, s2::ss) = 
        if s1 = s2 
        then SOME ss 
        else case remove_option (s1, ss) of 
           NONE => NONE 
          | SOME ss' => SOME (s2::ss') 
    

    Im Allgemeinen, wenn Sie das Muster sehen

    case x_opt of 
        NONE => NONE 
        | SOME x => SOME (f x)) 
    

    das sein kann in die Verwendung von z Option.map : ('a -> 'b) -> 'a option -> 'b option:

    Option.map f x_opt 
    

    In diesem Fall

    fun curry f x y = f (x, y) 
    
    fun remove_option (s1, []) = NONE 
        | remove_option (s1, s2::ss) = 
        if s1 = s2 
        then SOME ss 
        else Option.map (curry op:: s2) (remove_option (s1, ss)) 
    

    wo curry op:: s2, die Funktion, die s2 vor einer Liste setzt.

+0

Was meinst du mit "injiziert"? Ich verstehe es intuitiv, basierend auf dem Code-Snippet, aber scheint hier eine eher technische Bedeutung zu haben. –

+0

Es bedeutet wahrscheinlich nur, was Sie denken, dass es bedeutet.Wenn 'remove_option' eine Funktion' string * string -> bool' als Argument angenommen hat, dann muss * 'a * kein Gleichheitstyp sein. –

+1

Oh, ok, also wurde es als Argument übergeben. Vielen Dank. Ich dachte du meinst etwas ähnliches wie das 'inject' hier: http://mlton.org/UniversalType –

5

Das Problem ist, dass Sie

eine string list option aber die Linie zurückkehren wollen
else x :: remove_option(str,xs) 

macht es den Anschein, dass Sie eine string list

zurückkehren wollen, was Sie mit dem Rückgabewert von remove_option(str,xs) tun müssen, ist

1) entscheiden, was zu tun ist, wenn es NONE

2) ist die String-Liste extrahiert strings (oder was auch immer Sie es nennen wollen), wenn sie von der Form ist SOME strings, tack x auf der Vorderseite der Liste, und rekombinieren sie mit SOME, bevor es zurückkehrt.

Sie scheinen mit dem Einsatz von case komfortabel, so könnte man es hier verwenden.

Verwandte Themen