【问题标题】:SML/NJ - Pattern Matching an Dynamic TypingSML/NJ - 匹配动态类型的模式
【发布时间】:2010-12-20 19:18:18
【问题描述】:

是否可以编写具有动态类型输入参数的函数? 我尝试了模式匹配,但显然它不是这样工作的。

我想做这样的事情:

fun firstStr (0,n:string) = n
  | firstStr (b:string,n:string) = if b>n then n else b;

谢谢。

【问题讨论】:

  • 如果有什么不清楚的地方,请评论我的回答。另外,如果您认为我的回答回答了您的问题,请将其标记为已接受。

标签: functional-programming sml smlnj


【解决方案1】:

稍微详细一点,假设你有两个参数,每个参数可以是一个字符串或一个整数,如果你有两个字符串,你想要字典上更小的字符串,如果你有一个字符串,你想要那个字符串,并且如果您有两个整数,则不能返回字符串。你做什么工作?返回string option 类型的值(在http://www.standardml.org/Basis/option.html 查找optionSOMENONE):

datatype string_or_int = String of string
                       | Int    of int 

fun firstStr(String a, String b) = SOME (if a < b then a else b)
  | firstStr(String a, Int _   ) = SOME a
  | firstStr(Int _,    String b) = SOME b
  | firstStr(Int _,    Int _   ) = NONE

函数firstStr 有类型

string_or_int * string_or_int -> string option

成为精通 ML 程序员的最快方法是首先学会思考类型。例如,如果你真正想要的是一个string option * string -&gt; string 类型的函数,你就不需要自己写了;内置函数getOpt 就是这样做的。另一方面,听起来你想要string option * string -&gt; string,所以你可以写

fun firstStr(SOME a, b) = if a < b then a else b
  | firstStr(NONE,   b) = b

你不需要 SOME 值构造函数或 option 结果类型。

【讨论】:

  • 字符串选项类型正是我想要的:fun firstStr (NONE,n:string) = SOME n | firstStr (SOME b,n:string) = SOME (if b>n then n else b);
【解决方案2】:

StandardML 是一种严格的静态类型语言。因此,你不能有一个函数在第一种情况下接受一个 int 而在第二种情况下接受一个字符串。你得到的错误是

this clause:        string * string -> 'Z
previous clauses:      int * string -> 'Z
in declaration:
  firstStr =
    (fn (0,<pat> : string) => n
      | (<pat> : string,<pat> : string) => if <exp> > <exp> then n else b)

如果你想要一个 case 是 string,一个 case 是 int,你可以创建一个新类型,“tagged union”(又名“discriminated union”),它被设计成易于与模式匹配一​​起使用。它看起来像这样:

datatype Wrapper = Int    of int
                 | String of string
fun firstStr(Int 0,    n:string) = n
  | firstStr(String b, n:string) = if b>n then n else b

当然,您可能希望为这个 Wrapper 类型找到一些更合适的名称,这在您的程序上下文中是有意义的。另请注意,n 上的类型注释并不是真正需要的;写起来会更地道

fun firstStr(Int 0,    n) = n
  | firstStr(String b, n) = if b>n then n else b

另外,编译器会告诉你有一个未发现的情况:如果第一个参数是一个不等于 0 的整数怎么办?

最后,不太清楚你所说的比较b&gt;n是什么意思,你想比较两个字符串的哪个方面?我看到当我在 SML 中比较两个字符串时,我看到了一个字典(又名字母)比较。这是你想要的吗?

【讨论】:

    【解决方案3】:

    OCaml 中的Polymorphic variants 具有更多您正在寻找的动态属性。想看的可以看一下,OCaml 和 SML 是非常接近的语言。

    【讨论】:

      猜你喜欢
      • 2014-09-30
      • 2018-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-30
      • 1970-01-01
      • 2017-06-10
      • 1970-01-01
      相关资源
      最近更新 更多