Miranda語言
Miranda,是一種惰性求值的純函數式編程語言,由英國學者大衛·特納所設計。採用來自ML與Hope語言的概念,他用此來作為他先前所設計的SASL與KRC語言的後繼者[2]。這個程式語言由英國的研究軟件公司出品,這間公司擁有這個程式語言的商標權。
編程範型 | 惰性求值, 純函數式, 聲明式 |
---|---|
設計者 | 大衛·特納 |
實作者 | Research Software Ltd |
釋出時間 | 1985年 |
當前版本 |
|
型態系統 | 強類型, 靜態 |
許可證 | 二條款BSD許可證 |
網站 | Miranda homepage |
主要實作產品 | |
Miranda | |
啟發語言 | |
KRC, ML, SASL, Hope | |
影響語言 | |
Clean, Haskell, Orwell |
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).