哪些不只是函数式的语言有代数数据类型(或类似的数据类型)和模式匹配?我对多范式语言也很感兴趣--我知道Ocaml和F#是添加了OO的ML方言,所以它们继承了ML的代数数据类型。
可以使用enum
s和union
s (就像C中的C++,...more?)来模拟它们,但是这很快就变得麻烦和丑陋,如果您在模式匹配中忘记了大小写,或者(更可能的,也更危险的)在以“错误的方式”访问联合时,编译器不会警告您,例如,当它实际上是一个Left
值时,您请求一个Right
值的字段(然后您得到的是对恰好存在的位的无意义的重新解释)。
我听说Pascal has something like tagged unions和Cyclone language也支持带标签的联合。维基百科还提到了Ada和Algol。还有其他语言吗?
(如果您从未听说过代数数据类型,您可以阅读an Answer to "What is 'Pattern Matching' in functional languages?"以获得极好的介绍)。
发布于 2010-10-19 12:37:54
在Scala中,您通常使用case class
es来模拟在ML和Haskell等真正的函数式语言中可以找到的代数数据类型。
例如,以下F#代码(取自here):
type Shape =
| Circle of float
| EquilateralTriangle of double
| Square of double
| Rectangle of double * double
let area myShape =
match myShape with
| Circle radius -> Math.PI * radius * radius
| EquilateralTriangle s -> (sqrt 3.0) / 4.0 * s * s
| Square s -> s * s
| Rectangle (h, w) -> h * w
可以大致翻译成Scala,如下所示:
sealed abstract class Shape
case class Circle(radius: Float) extends Shape
case class EquilateralTriangle(side: Double) extends Shape
case class Square(side: Double) extends Shape
case class Rectangle(height: Double, width: Double) extends Shape
def area(myShape: Shape) = myShape match {
case Circle(radius) => math.Pi * radius * radius
case EquilateralTriangle(s) => math.sqrt(3.0) / 4.0 * s * s
case Square(s) => s * s
case Rectangle(h, w) => h * w
}
上面的sealed
关键字用于让编译器在您忘记match
表达式中的任何case
时发出警告。
发布于 2013-01-18 18:45:34
在Mozilla的Rust语言中,代数数据类型和模式匹配是重要的概念。语法也相当不错。考虑下面这个简单的程序:
static PI: f32 = 3.14159;
enum Shape {
Circle(f32),
Rectangle(f32, f32),
Point
}
fn area(shape: Shape) -> f32 {
match shape {
Point => 0.0
Circle(radius) => PI * radius * radius,
Rectangle(width, height) => width * height,
}
}
fn main() {
let radius = 4.0;
let circle = Circle(radius);
let area = area(circle);
println!("The area of a circle with radius {} is {}", radius, area);
}
发布于 2010-10-18 20:43:21
逻辑编程语言墨丘利称它们为discriminated unions。约束语言CHR,嵌入在Prolog和has them中,但它们是完全可选的,一般的Prolog术语是默认类型。
https://stackoverflow.com/questions/3963026
复制