Case 语句和模式匹配

发布于 2024-12-10 07:42:28 字数 1016 浏览 0 评论 0原文

我正在为一项作业使用 SML 进行编码,并且已经完成了一些练习题,但我觉得我错过了一些东西 - 我觉得我使用了太多 case 语句。这是我正在做的事情以及我遇到的问题的问题陈述:

  1. 编写一个函数 all_except_option,它接受一个字符串和一个字符串列表。如果字符串不在列表中,则返回 NONE,否则返回 SOME lst,其中 lst 类似于参数列表,只是字符串不在其中。

    fun all_ except_option(str : 字符串, lst : 字符串列表) =
      案例列表 
       [] =>没有任何
      | x::xs =>案例 Same_string(x, str) of
                   真=>一些xs
                 |假=>案例 all_except_option(str, xs) of
                              无=>没有任何
                            |一些 y=>一些(x::y)  
    
  2. 编写一个函数 get_substitutions1,它接受一个字符串列表 list(字符串列表、替换项的列表)和一个字符串 s 并返回一个字符串列表。结果包含替换中某个列表中也包含 s 的所有字符串,但 s 本身不应出现在结果中。

    fun get_substitutions1(lst : 字符串列表 list, s : 字符串) = 
      案例列表
        [] => []
      | x::xs =>案例 all_ except_option(s, x) of
                     无=> get_substitutions1(xs, s)
                    |一些 y => y @ get_substitutions1(xs, s)
    

- same_string 是提供的函数, 有趣的same_string(s1:字符串,s2:字符串)= s1 = s2

I'm coding in SML for an assignment and I've done a few practice problems and I feel like I'm missing something- I feel like I'm using too many case statements. Here's what I'm doing and the problem statements for what I'm having trouble with.:

  1. Write a function all_except_option, which takes a string and a string list. Return NONE if the string is not in the list, else return SOME lst where lst is like the argument list except the string is not in it.

    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)  
    
  2. Write a function get_substitutions1, which takes a string list list (a list of list of strings, the substitutions) and a string s and returns a string list. The result has all the strings that are in some list in substitutions that also has s, but s itself should not be in the result.

    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)
    

-
same_string is a provided function,
fun same_string(s1 : string, s2 : string) = s1 = s2

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

丘比特射中我 2024-12-17 07:42:28

首先,我将开始在函数定义中使用模式匹配
而不是“顶级”案例陈述。它基本上可以归结为
脱糖后也是同样的情况。另外,除非严格需要,否则我会摆脱显式类型注释:

fun all_except_option (str, []) = NONE
  | all_except_option (str, 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)

fun get_substitutions1 ([], s) = []
  | get_substitutions1 (x :: xs, s) =
    case all_except_option(s, x) of
      NONE   => get_substitutions1(xs, s)
    | SOME y => y @ get_substitutions1(xs, s)

如果速度不重要,那么您可以合并第一个函数中的两种情况:

fun all_except_option (str, []) = NONE
  | all_except_option (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 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)

但这只是我的首选方式,如果我真的必须添加类型注释。

顺便问一下,为什么要有 same_string 函数?您可以直接进行比较。使用辅助函数只是很奇怪,除非您计划在某个时候将其与某些特殊逻辑进行交换。然而你的函数名称并不表明这一点。

First of all I would start using pattern matching in the function definition
instead of having a "top-level" case statement. Its basically boils down to the
same thing after de-sugaring. Also I would get rid of the explicit type annotations, unless strictly needed:

fun all_except_option (str, []) = NONE
  | all_except_option (str, 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)

fun get_substitutions1 ([], s) = []
  | get_substitutions1 (x :: xs, s) =
    case all_except_option(s, x) of
      NONE   => get_substitutions1(xs, s)
    | SOME y => y @ get_substitutions1(xs, s)

If speed is not of importance, then you could merge the two cases in the first function:

fun all_except_option (str, []) = NONE
  | all_except_option (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)

But since you are using append (@), in the second function, and since it is not
tail recursive, I don't believe that it your major concern. Keep in mind that
append is potential "evil" and you should almost always use concatenation (and
then reverse your result when returning it) and tail recursion when possible (it
always is).

If you really like the explicit type annotations, then you could do it like this:

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)

But that is just my preferred way, if I really have to add type annotations.

By the way, why on earth do you have the same_string function? You can just do the comparison directly instead. Using an auxilary function is just wierd, unless you plan to exchange it with some special logic at some point. However your function names doesn't sugest that.

最美不过初阳 2024-12-17 07:42:28

除了 Jesper.Reenberg 提到的内容之外,我只是想提一下,bool 上的 truefalse 匹配可以替换为如果-那么-else。然而,有些人认为 if-then else 比 case 语句更难看

In addition to what Jesper.Reenberg mentioned, I just wanted to mention that a match on a bool for true and false can be replaced with an if-then-else. However, some people consider if-then-else uglier than a case statement

不可一世的女人 2024-12-17 07:42:28
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
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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文