2016년 12월 18일 일요일

Standard ML

Standard ML

Standard ML
Paradigm Multi-paradigm: Function type, order type
Model charge account StrongStaticThere is the reasoning
Main processing system MLton, MLWorks, Moscow ML, Poly/ML, SML/NJ, SML.NET
Dialect Alice, Dependent ML
The language that was affected ML

Standard ML (SML) is a standard of the programming language ML to 1 dialect. A model charge account rule and operational semantics are given in The Definition of Standard ML. A first edition is published in 1990, and version up simplified in 1997 is published [1].

Table of contents

Summary

The Standard ML is a functional language basically. Most of the programs written in Standard ML are comprised of the expression that should calculate a value.

It is a function, and, like other functional languages, the function to become the key to Standard ML thereby abstracts it. For example, the factorial function is expressed as follows.

    fun factorial x =         if x = 0 then 1 else x * factorial (x-1)  

The compiler of the Standard ML is int from the description that a user does not appoint data type at all in this way -> It is necessary to reason with a model called int statically. In other words, because x is used only in the expression of the integer, itself reasons that it is an integer and must reason that all the values brought about in the expression in the function are integers.

I can express the same function by "a knob function definition" (clausal function definition). It is '| by condition divergence called that case if-then-else I replace it with a series of templates divided in 'and, as for the individual templates, am evaluated a specific value. Each template is tried in turn and will find a thing fitting it.

    fun factorial 0 = 1      | factorial n = n * factorial (n -1)   

Using a local function, I can transfer this function to end recurrence.

    fun factorial x =        let            fun tail_fact p 0 = p              | tail_fact p n = tail_fact (p * n) (n -1)        in            tail_fact 1 x        end 

The let--style value is the price of the ceremony sandwiched between in and end.

Module system

The Standard ML has a high module system and can dismantle a program logically at an associated model and the hierarchy by structure of the declaration of the value. Not only I control merely namespace, but also the SML module has the role of the abstraction, and the programmer can define the abstract data type using this.

SML module system is comprised of three syntactic elements mainly. It is signature and structure and functor. structure is module itself. It is a model, an expression, a value, aggregate of structure (substructure) and packages them to one logic unit. signature is an interface and is recognized as a model of structure generally. I appoint the name of all substance which structure provides and appoint アリティ of the model element, model of the value element, signature of substructure. When I export, I may not do the definition of the model element either. I call the model element which concealed a definition "an abstract type" (abstract type). functor is functions from structure to structure. In other words, functor accepts one or more arguments (structure which I usually appointed in signature) and, as a result, generates structure. functor is used to implement generic data structure and algorithm.

For example, signature of the cue data structure is as follows.

 signature QUEUE =  sig    type 'a queue    Exception Queue    val empty: 'a queue    val insert: 'a * 'a queue -> 'a queue    val isEmpty: 'a queue -> bool    val peek: 'a queue -> 'a     val remove: 'a queue -> 'a * 'a queue end 

This signature describes a module providing model queue made the parameter of the cue and describes five values (as for four of them a function) to provide an exception called Queue, the basic operation of the cue in it. I can write structure which implemented cue data structure using this.

 structure TwoListQueue:> QUEUE =  Struct    type 'a queue = 'a list * 'a list    Exception Queue    val empty = ([], [])    fun insert (a,(ins,outs)) = (a::ins,outs)    fun isEmpty ([], []) = true      | isEmpty _ = false    fun peek ([], []) = raise Queue      | peek (ins,[]) = hd (rev ins)      | peek (ins,a::outs) = a    fun remove ([], []) = raise Queue      | remove (ins,[]) =         let val newouts = rev ins        in (hd newouts,([],tl newouts))        end      | remove (ins,a::outs) = (a,(ins,outs))  end 

By this definition, I declare that TwoListQueue is implementation of signature called QUEUE. Furthermore, (:> The model element that a definition is not provided in this signature (i.e., queue) by) opaque ascription appointed で shows that I treat it as an abstract type. In other words, a cue is defined by two lists here, but it does not show it in the module outside. The implementation corresponding to all elements which signature includes in the structure body is described.

You should access the member such as the model and value in "a dot scale" to use structure. For example, the model of the cue of the character string should write string TwoListQueue.queue, the queue of sky with TwoListQueue.remove q to delete TwoListQueue.empty, the first element of the cue called q.

Example code

I can carry out the cord piece easily by pro-handling of SML most include interactive top-level and inputting it. I reason, and this evaluates the model of the input expression. For example, in SML/NJ, it starts as follows.

   $ sml   Standard ML of New Jersey v110.52 [built: Fri Jan 21 16:42:10 2005]   - 

The cord inputs at the position of the prompt of "-". For example, I am as follows when I calculate 1+2*3.

   - 1 +2 * 3,   It is int val it = 7 

The top-level reasons that the model of the expression is "int" and displays value "7".

Hello world

It is said that there is following program "hello.sml".

   print "Hello world!\n"; 

When I compile this in MLton, I input as follows.

   $ mlton hello.sml 

The practice is as follows.

   $ ./hello   Hello world!   $ 

Merge sort

About the algorithm of the merge sort, see the article concerned. I implement a merge sort in three function split, merge, MergeSort here.

Function split implements it using local function split_iter having an additional argument. This is the technique that is convenient for implementation of the end recurrence. This function uses the pattern matching sentence structure of SML and defines the empty case ('[]') as case ('x::xs') where a list is not empty.

 (given the list of * elements the size about the same in it  * I divide it into two.  * O(n)  *) local  fun split_iter (x::xs, left, right) = split_iter(xs, right, x::left)  |   split_iter ([], left, right) = (left, right) in  fun split(x) = split_iter(x,[],[]) end; 

An equivalent definition is provided when I replace a sentence structure called local-in-end with a sentence structure called let-in-end.

 fun split(x) =  let   fun split_iter (x::xs, left, right) = split_iter(xs, right, x::left)   |   split_iter ([], left, right) = (left, right)  in   split_iter(x,[],[])  end; 

Like split, I promote efficiency of merge using local function merge_iter. I define some cases (when both are empty when one is empty when a handed list is empty neither) in merge_iter. '_' expresses a wild card pattern.

This function merges a list of two ascending order into a list of one descending order. It depends on the structure on the list in SML to come from behind. Because I implement a list with a tree in SML for nonequilibrium two minutes, it is easy to give it with an element in the lead, but what I give to the tail is inefficient.

 (I merge a list of ascending order of * two into a list of one descending order.  * Function lt(a,b) is a <b and the equivalent  * O(n)  *) local  fun merge_iter (out, left as (x::xs), right as (y::ys), lt) =      if lt(x, y)       then merge_iter(x::out, xs, right, lt)       else merge_iter(y::out, left, ys, lt)  |   merge_iter (out, x::xs, [], lt) = merge_iter (x::out, xs, [], lt)  |   merge_iter (out, [], y::ys, lt) = merge_iter (y::out, [], ys, lt)  |   merge_iter (out, [], [], _) = out in  fun merge(x,y,lt) = merge_iter([],x,y,lt) end;  

Finally I show below MergeSort function.

 (I sort a list of * in descending order.as for the order lt(a,b) <= => It is decided in a <b.  * O(n log n)  *) fun MergeSort(empty as _) = empty |   MergeSort(single as _::[], _) = single |   MergeSort(x, lt) =     let      val (left, right) = split(x)      val sl = MergeSort(left, lt)      val sr = MergeSort (right, lt)      val s = merge(sl,sr,lt)     in      rev s     end; 

In addition, as can be seen, it does not prescribe the model of the element with this cord. Therefore I can sort any type of element if there is even order function lt. By the model reasoning, the compiler can reason with the model of every variable including the complicated model such as the lt function.

Factorial function (library) of any precision

In SML, I offer the arithmetic of the integer of any precision (many double long precision) in IntInf module. A programmer less has to mind it if I say even if there is the number of the figures as for the integer to appear in a cord how long.

Next program "fact.sml" implemented a factorial function of any precision, and displays 120 factorial.

   fun fact n: IntInf.int =       if n=0 then 1 else n * fact(n -1)      val () =       print (IntInf.toString (fact 120) ^"\n") 

When I compile it and carry it out, I am as follows.

   $ mlton fact.sml   $ ./fact   66895029134491270575881180540903725867527463331380298102956713523016335   57244962989366874165271984981308157637893214090552534408589408121859898   481114389650005964960521256960000000000000000000000000000 

Numerical value differential calculus (Takashina function)

Because SML is a functional language, it is easy to be formed, and to handle a function. Various application is thought about in this. The numerical value differential calculus of the function is one, too. Following SML function "d" calculates numerical value differential calculus in "x" of given function "f".

   - fun d delta f x =       (f (x + delta) - f (x - delta)) / (2.0 * delta),   val d = fn: real -> (real -> real) -> real -> real 

This function needs small value "delta". For example, I can use the cubic root of the machine epsilon as delta.

The model of function "d" is model "(real -> real) -> real -> I give "real" to a different function having real". In this way, curry calls a method "doing a function in a function to return the function that takes the argument of numbers fewer than all necessary arguments, and takes the remaining argument" with making it it. It comes to be in this way possible to apply only part of argument (I say a partial application and warn a part application because there is not it, and it may be mentioned, "I return the thing which I make the function that there is curry and applied to it partially" with "I make it curry" by mistake). I appoint "delta" concretely here and get the function that I specialized more.

   - val d = d 1E~8;   val d = fn: (real -> real) -> real -> real 

An argument first in "d" which was replaced when I see a model reasoned here is "real -> It becomes the function of the model called real". Using this, I calculate, for example, the approximation of the differential calculus level at the age of x=3 in x^3-x-1.

   - d (fn x => x * x * x - x -1.0) 3.0,   It is real val it = 25.9999996644 

The right value is f'(x) = 3x^2-1 => It is f'(3) = 27-1 = 26.

Because function "d" takes different function "f" as an argument, I am called "Takashina function" (higher-order function).

Becoming it and the Takashina function can remove a redundant cord curry. For example, it is a to a library -> It is said that the function of the model called b is necessary. However, when have fixed relation to an a type and a c-shaped object; a * c -> One to write the function of the model called b is convenient. (a * c -> b) -> (a -> I can remove a common point if I use the Takashina function of the model called b). This is an example of the Adapter pattern.

Disintegration wavelet transform (pattern matching)

I can easily implement several lines of one-dimensional disintegration wavelet transform of the length of 2 整数乗 in SML and become the fine example of the pattern matching in the list. I take two elements ("h1" and "h2") out of the top on the list and store a difference share in the grand total in list "d" in list "s".

   - fun haar l =       let fun aux [s] [] d = s: d             | aux s d = aux s d             | aux (h1::h2::t) s d =               aux t (h1 + h2:: s) (h1 - h2:: d)             | aux _ _ _ = raise Empty       in aux l []       end;   val haar = fn: int list -> int list 

The practice examples are as follows.

   - haar [1, 2, 3, 4, ~4, ~3, ~2, ~1];   val it = [0,20,4,4,~1,~1,~1,~1]: int list 

The pattern matching can express complicated conversion definitely and briefly. Furthermore, not only merely cord becomes concise, but also is high-speed because the SML compiler generates the code that I optimized for a pattern matching.

Implementation

There is various implementation, but introduces a part here.

Each these is an open source. Processing system in itself is implemented a lot in SML. The commercial product of SML does not exist. A company called Harlequin developed and sold a commercial product called MLWorks once. The company has already gone bankrupt.

References

  • Jun Ohori "introduction to programming language Standard ML" Kyoritsu publication, Tokyo, September, 2001. ISBN 4-320-12024-8

Footnote

[Help]
  1. ^ Milner, R.; M. Tofte, R. Harper and D. MacQueen. (1997). The Definition of Standard ML (Revised). MIT Press. ISBN 0-262-63181-4. 

Outside link

This article is taken from the Japanese Wikipedia Standard ML

This article is distributed by cc-by-sa or GFDL license in accordance with the provisions of Wikipedia.

Wikipedia and Tranpedia does not guarantee the accuracy of this document. See our disclaimer for more information.

In addition, Tranpedia is simply not responsible for any show is only by translating the writings of foreign licenses that are compatible with CC-BY-SA license information.

0 개의 댓글:

댓글 쓰기