Miranda语言
编程范型 | 惰性求值, 纯函数式, 声明式 |
---|---|
设计者 | 大卫·特纳 |
实作者 | Research Software Ltd |
发行时间 | 1985年 |
当前版本 |
|
型态系统 | 强类型, 静态 |
许可证 | 二条款BSD许可证 |
网站 | Miranda homepage |
主要实作产品 | |
Miranda | |
启发语言 | |
KRC, ML, SASL, Hope | |
影响语言 | |
Clean, Haskell, Orwell |
Miranda,是一种惰性求值的纯函数式编程语言,由英国学者大卫·特纳所设计。采用来自ML与Hope语言的概念,他用此来作为他先前所设计的SASL与KRC语言的后继者[2]。这个编程语言由英国的研究软件公司出品,这间公司拥有这个编程语言的商标权。
Miranda在1985年首次发表以C语言写成的直译器,能够在类UNIX系统上运作。随后在1987年与1989年发行了更新版。Miranda强烈的影响了后来发展出的Haskell语言[3]。
概述
Miranda是惰性、纯函数式编程语言。就是说,它缺少副作用和指令式编程特征。一个Miranda程序(叫做脚本)定义数学函数和代数数据类型的一组等式。集合的概念在这里是重要的,即等式的次序一般而言是无关紧要的,并且不需要在使用之前定义一个实体。
词法
因为解析算法可以智能的利用布局(缩进),很少需要将语句用括号包围起来,并且不要求语句终止符。这个特征受到了ISWIM的启发,也被用于occam和Haskell中,后来经由Python而流行起来。
注释通过字符||
介入到正规的脚本中并持续到此行结束。一种可作为替代的注释约定影响整个源代码文件,叫做“文学脚本”,在其中所有的行都被当作注释,除非它开始于 >
符号。
数据类型
Miranda的基本数据类型是char
、num
和bool
。字符串简单的就是char
的列表,而num
在两种底层形式之间静默转换:缺省的任意精度整数(又名bignum),和需要时的正规浮点值。
元组是潜在混合类型的元素的序列,类似于类Pascal语言的记录,用圆括号来界定:
this_employee = ("Folland, Mary", 10560, False, 35)
列表是Miranda中最常用的数据结构。列表用方括号来界定并具有用逗号分隔的元素,它们都必须有着相同类型:
week_days = ["Mon","Tue","Wed","Thur","Fri"]
列表串接是++
,删减是--
,构造是:
,大小是#
而索引是!
,比如:
days = week_days ++ ["Sat","Sun"]
days = "Nil":days
days!0
⇒ "Nil"
days = days -- ["Nil"]
#days
⇒ 7
有一些列表建造捷径:..
用于其元素形成算数序列的列表,具有指定不是1的增量的可能:
fac n = product [1..n]
odd_sum = sum [1,3..100]
更一般性和更强力的列表建造设施是列表推导式(以前叫做“ZF表达式”),它以两种主要形式提供:应用于一系列项目的一个表达式,比如:
squares = [ n * n | n <- [1..] ]
它可以读作:n
的平方的列表,这里的n
取自所有正数的列表;和其中每个项目都是前一项目的函数的一个系列,比如:
powers_of_2 = [ n | n <- 1, 2*n .. ]
如这两个例子所蕴含的那样,Miranda允许无限数目元素的列表,其中最简单的是所有正数的列表:[1..]
。
函数
函数应用的表示法是简单的并列,比如sin x
这样。
在Miranda中,如同大多数其他纯函数式语言,函数是头等公民,就是说它们可以作为实际参数传递给其他函数,作为结果返回,被包括为数据结构的元素。进一步的,通过提供少于形式参数数目的实际参数,有两个或更多形式参数的函数可以部分的“参数化”,或柯里化。这给出了另一个函数,接受余下的形式参数,并返回一个结果。例如:
add a b = a + b
increment = add 1
是建立向它的实际参数加1
的一个函数“增加”的迂回方式。在现实中,add 4 7
接受两个形式参数,函数add
应用于4
将得到一个单一形式参数的函数,它向它的实际参数加4
,接着应用它于得到结果
7
。
任何有两个形式参数(操作数)的函数都可以转变成中缀算符,例如,给出上述的add
函数定义,项目$add
在所有方式下都等价于+
算符,而所有接受两个形式参数的中缀算符也可以转变成对应的函数。因此如下这样:
increment = (+) 1
是建立向其实际参数加1
的最简洁方式。类似的,在下列中:
half = (/ 2)
reciprocal = (1 /)
生成了两个单一形式参数的函数。解释器理解提供除法算符的两个形式参数的每种情况,分别给出将一个数除以2
和返回它的倒数的函数。
它有着建立和操纵程序模块的机制,其内部函数对于调用这些模块的程序是不可见的。
类型推论和多态
尽管Miranda是强类型编程语言,它不坚持于显式的类型声明。如果一个函数的类型没有明确的声明,解释器会从它的形式参数和它们在函数内如何使用来推论出它的类型。除了基本类型(char
、num
和bool
)之外,它包括了“任何事物”类型,这里一个形式参数的类型是无关紧要的,例如在列表反转函数中:
rev [] = []
rev (a:x) = rev x ++ [a]
它可以应用于有任何数据类型的列表,给它的显式的函数类型声明将是:
rev :: [*] -> [*]
样例代码
下列的Miranda脚本确定一个数的集合的所有子集的集合:
subsets [] = [[]]
subsets (x:xs) = [[x] ++ y | y <- ys] ++ ys
where ys = subsets xs
和函数primes
的文学脚本,它给出所有素数的列表:
> || The infinite list of all prime numbers.
The list of potential prime numbers starts as all integers from 2 onwards;
as each prime is returned, all the following numbers that can exactly be
divided by it are filtered out of the list of candidates.
> primes = sieve [2..]
> sieve (p:x) = p : sieve [n | n <- x; n mod p ~= 0]
引用
- ^ Miranda download page. [2024年5月17日].
- ^ Turner, D. A. Some History of Functional Programming Languages (PDF). [2020-04-25]. (原始内容存档 (PDF)于2020-04-15).
- ^ Hudak, Paul; Hughes, John. A History of Haskell: being lazy with class. 2007 [2021-02-27]. (原始内容存档于2016-12-26).