【问题标题】:creat a tuple by removing first element from another tuple in ML通过从 ML 中的另一个元组中删除第一个元素来创建一个元组
【发布时间】:2013-01-19 03:26:52
【问题描述】:

使用 ML 作为一种编程语言,我们有列表和元组,在列表的情况下,我们可以通过从原始列表中删除或附加元素来从另一个列表中形成一个列表,例如,如果我们有:

val x = [7,8,9] : int list  

在 REPL 中我们可以做如下一些操作:

- hd x;
val it = 7 : int
- tl x;
val it = [8,9] : int list 

现在如果我们有一个元组让我们说:

val y = (7,8,9) :int*int*int

现在的问题是,我们可以通过从原始元组中删除第一个元素来获得更小的元组吗?换句话说,如何删除(#1 y) 并拥有新的元组(8,9),其方式与我们在列表的情况下类似。

谢谢。

【问题讨论】:

    标签: tuples sml ml


    【解决方案1】:

    元组与列表非常不同。对于列表,大小不需要在编译时知道,但对于元组,不仅要在编译时知道元素的数量,而且每个元素的类型都独立于其他元素。

    tl的类型签名:

    - tl;
    val it = fn : 'a list -> 'a list
    

    它是 'a list -> 'a list - 换句话说,tl 接受 list'a 并返回另一个。为什么我们没有一个用于元组的呢?假设我们想要类似

    y = (1,2,3);
    tail y;        (* returns (2,3) *)
    

    为什么这没有意义?想想tail 的类型签名。那会是什么? 在这种情况下,它显然是

    'a * 'b * 'c -> 'b * 'c
    

    获取'a'b'c 的乘积并返回 'b'c。在 ML 中,所有定义的函数都必须具有静态确定的 类型签名。不可能有一个 tail 函数用于元组 处理所有可能的元组大小,因为每个元组大小本质上是一个不同的类型

    'a list
    

    可以是多种列表的类型:[1,2,3,4],或["A", "short", "sentence"],或 【真、假、假、真、假】。在所有这些情况下,类型的值 变量'a 绑定到不同的类型。 (整数、字符串和布尔值)。而'a list 可以是任意大小的列表。

    但是采用元组:

    (1, true, "yes");   (* (int * bool * string) *)
    ("two", 2)          (* (string, int) *)
    ("ok", "two", 2)    (* (string, string, int) *)
    

    与列表不同,这些都是不同的类型。因此,虽然所有列表的类型签名都很简单 ('a list),但所有元组都没有“通用类型”——2 元组与 3 元组的类型不同。

    所以你必须这样做:

    y = (7, 8, 9);
    (a, b, c) = y;
    

    a 是你的头部,你可以用 (b,c) 重新创建尾部。 或者创建自己的尾巴:

    fun tail (a,b,c) = (b, c)
    

    这也让我们直观地理解了为什么这样的函数没有意义:如果不可能定义单个 tail 用于所有元组类型:

    fun tail (a,b) = (b)
      | tail (a,b,c) = (b, c)  (* won't compile *)
    

    您还可以使用# 速记来获取元组的某些元素:

    #1 y;   (* returns 7 *)
    

    但请注意,#1 不是函数,而是编译时简写。

    【讨论】:

      【解决方案2】:

      列表和元组是不可变的,因此没有像从中删除元素这样的事情。

      你可以通过分解原始元组来构造一个新的元组。在 SML 中,首选的方式是使用模式匹配:

      fun getLastTwo (x, y, z) = (y, z)
      

      如果你喜欢#n 函数,你也可以使用它们:

      val xyz = (7, 8, 9)
      val yz = (#2 xyz, #3 xyz) (* (8, 9) *)
      

      【讨论】:

      • 也许最后一行必须是 val yz = (#2 xyz, #3 xyz) (* (8, 9) ) 而不是 val yz = (#2 xys, #3 xyz) ( (8, 9) *).
      猜你喜欢
      • 2019-02-16
      • 2017-02-25
      • 1970-01-01
      • 2016-10-31
      • 2012-06-19
      • 2018-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多