7
votes

Déclarations de cas et correspondance des motifs

Je codis dans SML pour une mission et j'ai fait quelques problèmes de pratique et je me sens que je me manque quelque chose, je me sens comme si j'utilise trop de caisse code>. Voici ce que je fais et les déclarations de problèmes pour ce que j'ai des problèmes.:

  1. écrire une fonction all_except_option, qui prend une chaîne et une liste de chaînes. Return None Si la chaîne ne figure pas dans la liste, sinon renvoyez une partie de la LST où la LST est comme la liste des arguments, à l'exception de la chaîne. p>

    fun get_substitutions1(lst : string list list, s : string) = 
      case lst of
        [] => []
      | x::xs => case all_except_option(s, x) of
                     NONE => get_substitutions1(xs, s)
                    | SOME y => y @ get_substitutions1(xs, s)
    
  2. écrire une fonction get_substitutions1, qui prend une liste de liste de chaînes (liste de la liste des chaînes, les substitutions) et une chaîne s et renvoie une liste de chaînes. Le résultat a toutes les cordes qui figurent dans une liste de substitutions qui y sont également, mais elles ne devraient pas être en résultat. p>

    fun all_except_option(str : string, lst : string list) =
      case lst of 
       [] => NONE
      | x::xs => case same_string(x, str) of
                   true => SOME xs
                 | false => case all_except_option(str, xs) of
                              NONE => NONE
                            | SOME y=> SOME (x::y)  
    


1 commentaires

Cela fait partie de la mission pour la semaine2 dans le cours Langues de programmation de Coursera. Comme il s'agit d'une violation pour poster des solutions en ligne, je demande à nouveau cette question pour modifier les noms de fonction afin de ne pas correspondre exactement à la mission.


3 Réponses :


11
votes

Tout d'abord, je commencerais à utiliser le motif correspondant dans la définition de la fonction au lieu d'avoir une déclaration de cas "de haut niveau". C'est fondamentalement se résume à la même chose après le sucre. De plus, je me débarrasserais des annotations de type explicites, sauf si vous n'avez strictement nécessaire:

val rec all_except_option : string * string list -> string list option  =
 fn (str, []) => NONE
  | (str, x :: xs) =>
    case (same_string(x, str), all_except_option(str, xs)) of
      (true, _)       => SOME xs
    | (false, NONE)   => NONE
    | (false, SOME y) => SOME (x::y)


val rec get_substitutions1 : string list list * string -> string list =
 fn ([], s) => []
  | (x :: xs, s) =>
    case all_except_option(s, x) of
      NONE   => get_substitutions1(xs, s)
    | SOME y => y @ get_substitutions1(xs, s)


3 commentaires

Lorsque j'essaie le bloc de code haut, je reçois des erreurs de compilation disant "Erreur: l'opérateur n'est pas une fonction" - On dirait que la section All_Except_Options (S, x) ne peut pas être séparée de get_substitutions1 (x :: xs, s ) bloquer. Comment puis-je dire SML qu'aucun et certains sont des cas pour ce qui est retourné par all_except_option et non cas pour GET_SUBSTIVES?


Vous pourriez dire que "le mot clé amusant brise les deux fonctions". Cela fonctionne dans SML / NJ 110.72, donc vous utilisez un autre interprète ou vous avez fait quelque chose de mal. Vous pouvez mettre l'expression de cas imbriquée entre parenthèses. Cependant, le message d'erreur que vous obtenez, ne sonne pas comme si cela a quelque chose à voir avec les cas?


@ Jesper.reenberg Je sais que c'est un vieux fil, mais j'essaie de casse-t-il ce qui est dans certains y dans all_except_option . Si vous le permettez de renvoyer un peu (x :: "wtf" :: y), vous pouvez voir que cela fonctionne sur tous les éléments avant de faire correspondre la chaîne, mais pas sur aucun élément après la correspondance de la chaîne. Si y contient le reste de la liste, pourquoi je ne vois pas la liste de la liste dupliquée? J'ai du mal à faire du mal à travers ce problème avec un tampon de papier et de garder une trace de ce que certains ont réellement pointé à chaque étape.



1
votes

En plus de ce que Jesper.reenberg a mentionné, je voulais juste mentionner qu'une correspondance sur un bool pour true et false peut être remplacé par un si - alors - sinon . Cependant, certaines personnes considèrent si - alors, aussi la plus laidienne qu'une déclaration de cas


1 commentaires

Vrai que je suppose que je suis une de ces personnes :)



0
votes
fun same_string( s1: string, s2: string ) = if String.compare( s1, s2 ) = EQUAL then true else false


fun contains( [],   s: string ) = false
|   contains( h::t, s: string ) = if same_string( s, h ) then true else contains( t, s )


fun all_except_option_successfully( s: string, [] )   = []
|   all_except_option_successfully( s: string, h::t ) = if same_string( s, h ) then t else ( h :: all_except_option_successfully( s, t ) )


fun all_except_option( s: string, [] )   = NONE
|   all_except_option( s: string, h::t ) = if same_string( s, h ) then SOME t else if contains( t, s ) then SOME ( h :: all_except_option_successfully( s, t ) ) else NONE

1 commentaires

Il y a toujours de la place pour optimiser un "si .. alors vrai sinon faux" :-)