【问题标题】:I get datatype, but what is the point of defining types in sml?我得到了数据类型,但是在 sml 中定义类型有什么意义呢?
【发布时间】:2013-03-15 02:20:35
【问题描述】:

在 SML 中定义类型似乎没什么帮助:

type point = int * int
val origin : point = (0, 0)

但是我可以很容易地使用int * int 来输入方法,不是吗?与 datatype 相比,您似乎可以用它做更多有趣的事情,例如:

datatype Point = PlanePoint of (int * int) | SpacePoint of (int * int * int)
val origin : Point = SpacePoint(0, 0, 0)

出于好奇,在哪些情况下您真的需要定义 type

【问题讨论】:

    标签: sml


    【解决方案1】:

    原因主要是类型安全。我将尝试用一个简单的例子来解释。

    假设您有一个模块使用 2 种类型,用 real * real 表示 例如,您的示例中的 2d 点,以及由斜率和 y 截距表示的线。现在,如果您正在编写像 lies_on_line 这样的函数,它接受一个点和一条线,并返回一个布尔值是否该点位于线上,您有 2 个签名选择:

    val lies_on_line : (int * int) * (int * int) -> bool
    

    排序

    val lies_on_line : point * line -> bool 
    

    很明显,第二个例子更难出错。

    此外,虽然它对模块更有好处,但命名类型允许您更改其表示,而无需更改使用该类型的代码(间接通过模块)。

    【讨论】:

    • 那么好的编程比在模块之外绝对必要吗?
    • 是的,它完全是可选的。就我个人而言,除非我打算稍后更改具体类型,否则我不会经常这样做。但是,我使用 OCaml,它也具有标记参数,这些参数在使用中重叠并且更轻量级。这主要是个人喜好。
    • 这似乎是错误的。这两个签名是等价的,所以除非我误解你所说的“类型安全”是什么意思,否则这里没有提供。该语言允许类似type myInt = intval x = 3 : myIntval y = x : int。如果您想要一个独特的签名,具有编译器强制类型安全和错误预防,您需要使用datatype 作为OP 建议:type myInt = MY_INT of int val x = MY_INT 3 val MY_INT y = x
    • 这是真的,你必须使 pointline 抽象来实现某种类型安全。我对 SML 不太熟悉,无法记住如何处理,但使用 OCaml,您只需在 mli 中定义 type pointtype line
    【解决方案2】:

    在您的问题域的上下文中为您的类型定义别名是有意义的。这样,您就可以在设计中考虑更相关和更有意义的类型。

    例如,如果您正在编写文字处理器程序,那么您的类型如下:

    type Word = string
    type Sentence = Word list
    

    这可能比字符串和字符串列表更有意义。

    【讨论】:

      猜你喜欢
      • 2017-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-04
      • 2021-02-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多