模式匹配SML?

时间:2017-01-25 05:53:00

标签: functional-programming sml ml

有人可以解释一下:“g的描述”? f1如何获取单位并返回一个int&其余的我也很困惑!!

(* Description of g:
 * g takes f1: unit -> int, f2: string -> int and p: pattern, and returns 
 * an int. f1 and f2 are used to specify what number to be returned for 
 * each Wildcard and Variable in p respectively. The return value is the 
 * sum of all those numbers for all the patterns wrapped in p.
 *)  

datatype pattern = Wildcard
                 | Variable of string
                 | UnitP
                 | ConstP of int
                 | TupleP of pattern list
                 | ConstructorP of string * pattern

datatype valu = Const of int
              | Unit
              | Tuple of valu list
              | Constructor of string * valu


fun g f1 f2 p =
    let
      val r = g f1 f2
    in
      case p of
           Wildcard           => f1 ()
         | Variable x         => f2 x
         | TupleP ps          => List.foldl (fn (p,i) => (r p) + i) 0 ps
         | ConstructorP (_,p) => r p
         | _                  => 0
    end

通配符匹配所有内容并生成空的绑定列表。

变量s 匹配任何值v并生成保存(s,v)的单元素列表。

UnitP 仅匹配单位并生成空的绑定列表。

ConstP 17 仅匹配Const 17并生成空的绑定列表(对于其他整数也是如此)。

TupleP ps 匹配Tuple vs形式的值,如果ps和vs具有相同的长度,对于所有i,ps的第i个元素匹配vs的第i个元素。生成的绑定列表是附加在一起的嵌套模式匹配的所有列表。

ConstructorP(s1,p)匹配构造函数(s2,v),如果s1和s2是相同的字符串(可以将它们与=进行比较),p匹配v。生成的绑定列表是嵌套模式匹配的列表。我们将字符串s1和s2称为构造函数名称。

没有其他东西匹配。

1 个答案:

答案 0 :(得分:2)

  

有人可以解释一下:“g的描述”? f1如何获取单位并返回一个int&其余的我也很困惑!!

  • 函数g的类型为(unit→int)→(string→int)→pattern→int ,因此需要三个(curried)参数,其中两个是函数和一个是模式

  • 参数f1f2必须是始终返回相同常量的确定性函数,或者具有可以分别返回任意整数/字符串的副作用的函数,由外部来源。

    由于评论中提到“每个通配符和变量返回的数字”,因此f1听起来更有可能在不同时间返回不同的数字(而且我'在f2的情况下,我不确定数字是指什么!一个定义可能是这样的:

    local
        val counter = ref 0
    in
        fun uniqueInt () = !counter before counter := !counter + 1
        fun uniqueString () = "s" ^ Int.toString (uniqueInt ())
    end
    

    虽然这只是猜测。此定义仅适用于Int.maxInt

  • 评论将g的返回值描述为

      

    [...]包含在p。

    中的所有模式的所有数字的总和

    由于这些数字没有任何意义,似乎g似乎没有任何实际意义,只是比较任意给定的f1f2组的输出。没有给出的任意测试。

  • Catch-all模式通常很糟糕:

      ...
    | _ => 0
    
         

    没有其他东西匹配。

    原因是如果使用其他类型的模式扩展 pattern ,编译器将不会在函数g中通知您缺少模式;对于可能尚未定义的案例,一切都将错误地暗示意义。