1种情况下的多种模式

时间:2016-04-01 03:46:59

标签: sml smlnj

在SML中,您是否可以在一个case语句中使用多个模式?

例如,我有4个算术运算符以字符串"+", "-", "*", "/"表示,我想打印"PLUS MINUS"的{​​{1}}和"+" or "-"如果是"MULT DIV" }}

TL; DR:有什么地方可以简化以下内容以减少使用情况吗?

"*" or "/"

3 个答案:

答案 0 :(得分:7)

鉴于您已使用标记标记了您的问题,那么是的,SML / NJ支持这种模式。他们称之为or-patterns,它看起来像这样:

case str of
  ("+" | "-") => print "PLUS MINUS"
| ("*" | "/") => print "MULT DIV"

注意括号。

MLton的主分支也支持它,作为Successor ML effort的一部分,但你必须自己编译MLton。

val str = "+"

val _ =
  case str of
    "+" | "-" => print "PLUS MINUS"
  | "*" | "/" => print "MULT DIV"

请注意,MLton不需要parantheses。现在使用此命令编译它(与SML / NJ不同,您必须在MLton中显式启用此功能):

mlton -default-ann 'allowOrPats true' or-patterns.sml

答案 1 :(得分:2)

在标准ML中,没有。在ML的其他方言中,例如OCaml,是的。在某些情况下,您可能会考虑将模式匹配拆分为单独的案例/函数,或者跳过模式匹配以支持更短的catch-all表达式,例如

if str = "+" orelse str = "-" then "PLUS MINUS" else
if str = "*" orelse str = "/" then "MULT DIV" else ...

答案 2 :(得分:0)

扩展Ionuţ的示例,您甚至可以使用其他类型的数据类型,但它们的类型(和标识符赋值)必须匹配:

datatype mytype = COST as int | QUANTITY as int | PERSON as string | PET as string;

case item of
  (COST n|QUANTITY n) => print Int.toString n
  |(PERSON name|PET name) => print name

如果类型或名称不匹配,则会被拒绝:

case item of
  (COST n|PERSON n) => (* fails because COST is int and PERSON is string *)
  (COST n|QUANTITY q) => (* fails because the identifiers are different *)

这些模式也适用于函数定义:

fun myfun (COST n|QUANTITY n) = print Int.toString n
   |myfun (PERSON name|PET name) = print name
;