首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SML如何实现抽象?

SML如何实现抽象?
EN

Stack Overflow用户
提问于 2014-12-10 00:25:27
回答 3查看 250关注 0票数 0

我是SML的新手,这是我第一次学习函数式语言。我认为SML是抽象的。我还没有找到关于如何在SML中实现抽象的完美解释。有人能给出一个解释吗?

EN

回答 3

Stack Overflow用户

发布于 2014-12-25 18:26:45

一般来说,在编程中至少有两种形式的“抽象”:

将客户端抽象为implementation (encapsulation)的

(如果您关心,这些对应于逻辑和类型理论中的普遍和存在量化。)

在ML中,参数化可以在两个级别上完成。在小范围内,使用函数(值的抽象)和多态性(类型的抽象)。特别要注意的是,函数是一流的,所以您可以将一个函数参数化。例如:

代码语言:javascript
复制
fun map f []      = []
  | map f (x::xs) = f x :: map f xs

抽象了转换函数f以及元素类型上的列表转换。

大体上,参数化可以使用模块系统来完成:函数器将整个模块抽象为另一个模块(即,值和类型)。例如,您还可以将map函数编写为functor:

代码语言:javascript
复制
functor Mapper(type t; type u; val f : t -> u) =
struct
  fun map []      = []
    | map (x::xs) = f x :: map xs
end

但通常情况下,你会使用函数式来进行大量抽象,也就是说,当你需要参数化的函数不止一个的时候。

封装也是通过使用模块实现的。具体地说,通过密封它们,即在签名后面隐藏它们类型的细节。例如,下面是一个整数集的(朴素的)实现:

代码语言:javascript
复制
signature INT_SET =
sig
  type set
  val empty : set
  val add : int * set -> set
  val mem : int * set -> bool
end

structure IntSet :> INT_SET =  (* ':>' hides the implementation of type set *)
struct
  type set = int list
  val empty = []
  fun add(x, s) = x::s
  fun mem(x, s) = List.exists (fn y => y = x) s
end

在结构IntSet之外,它的类型set是完全抽象的,也就是说,它不能与lists互换。这就是模块的所谓密封操作符:>的目的。

这两种形式的抽象可以一起发生。例如,在ML中,人们通常会将一个set实现为一个functor:

代码语言:javascript
复制
signature ORD =
sig
  type t
  val compare : t * t -> order
end

signature SET =
sig
  type elem
  type set
  val empty : set
  val add : elem * set -> set
  val mem : elem * set -> bool
end

functor Set(Elem : ORD) :> SET where type elem = Elem.t =
struct
  type elem = Elem.t
  datatype set = Empty | Branch of set * elem * set

  val empty = Empty

  fun add(x, Empty) = Branch(Empty, x, Empty)
    | add(x, Branch(l, y, r)) =
      case Elem.compare(x, y) of
        LESS => Branch(add(x, l), y, r)
      | EQUAL => Branch(l, y, r)
      | GREATER => Branch(l, y, add(x, r))

  fun mem(x, Empty) = false
    | mem(x, Branch(l, y, r)) =
      case Elem.compare(x, y) of
        LESS => mem(x, l)
      | EQUAL => true
      | GREATER => mem(x, r)
end

sets的这种实现适用于任何可以提供排序功能的类型。与以前的朴素实现不同,它还使用了更高效的搜索树作为其实现。但是,这在外部是不可见的,因为类型的实现再次被隐藏。

票数 6
EN

Stack Overflow用户

发布于 2014-12-10 21:59:33

SML程序通常建立在针对手头问题的描述性类型之上。然后,该语言使用模式匹配来找出您正在处理的案例。

代码语言:javascript
复制
datatype Shape = Circle of real | Rectangle of real*real | Square of real

val a = Circle(0.2)
val b = Square(1.3)
val c = Rectangle(4.0,2.0)

fun area (Circle(r)) = 3.14 * r * r
  | area (Square(s)) = s * s
  | area (Rectangle(b,h)) = b * h

这对解释一下sml有帮助吗?

票数 1
EN

Stack Overflow用户

发布于 2014-12-25 02:14:47

在SML中,您可以通过组合使用代数数据类型和签名来定义“抽象”。

代数数据类型允许您定义特定于问题域的新类型,而签名允许您围绕这些类型提供功能/行为,并提供一种实现信息隐藏、可扩展性和可重用性的便捷方法。

结合这些东西,你可以创建“抽象”,它的实现细节对你是隐藏的,你只需通过它们的公共接口就能理解(无论签名公开了什么)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27383861

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档