Created
January 23, 2019 03:38
-
-
Save sourabhxyz/2320042c472366cd5488c31f0ca52bd9 to your computer and use it in GitHub Desktop.
SML Cheat Sheet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val real_division = 14.0 / 4.0 (* gives 3.5 *) | |
val int_division = 14 div 4 (* gives 3, rounding down *) | |
val int_remainder = 14 mod 4 (* gives 2, since 3*4 = 12 *) | |
(* andalso is same as && in c, orelse is same as || in c, not is the negation) | |
(* Many values can be compared using equality operators: = (==) and <> (!=) *) | |
list is written as "type list" | |
list is homogenous, list can only contain one type of thing. | |
'@' / '^' for list / string resp | |
- (2::4::6::nil) :: (2::3::5::7::nil) :: (2::4::8::16::32::nil) :: nil; | |
val it = [[2,4,6],[2,3,5,7],[2,4,8,16,32]] : int list list | |
val x : int = 3; | |
val x = 3 : int; (* both are valid *) | |
(* We can give new names to types. This is called type aliasing *) | |
type vector2d = real * real | |
val unitx : vector2d = (1.0,0.0) (* unit vector along x-axis *) | |
val unity : vector2d = (0.0,1.0) (* unit vector along y-axis *) | |
(* Tuples, on the other hand, can contain a fixed number of different things *) | |
val it = () : unit | |
- ((2,3,4), (true,3.3)); | |
val it = ((2,3,4),(true,3.3)) : (int * int * int) * (bool * real) | |
false, true is for boolean | |
- fun (* mutually recursive function definitions *) | |
= take nil = nil | take (x::xs) = x::(skip xs) | |
= and | |
= skip nil = nil | skip (x::xs) = take xs; | |
val take = fn : 'a list -> 'a list | |
val skip = fn : 'a list -> 'a list | |
- fun merge (xs,nil) = xs | |
= | merge (nil,ys) = ys | |
= | merge (x::xs,y::ys) = if x<y then x :: merge(xs,y::ys) else y :: merge(x::xs,ys); | |
- nil; | |
val it = [] : 'a list | |
- val curry = (fn f => (fn a => fn b => f(a,b))); | |
val curry = fn : ('a * 'b -> 'c) -> 'a -> 'b -> 'c | |
- fun curry (f) (a) (b) = f(a,b); | |
val curry = fn : ('a * 'b -> 'c) -> 'a -> 'b -> 'c | |
- fun curry f a b = f (a, b) | |
- fun uncurry f (a,b) = f a b; | |
val uncurry = fn : ('a -> 'b -> 'c) -> 'a * 'b -> 'c | |
(* in uncurry "= f a b" means ((f a) b) *) | |
- fun add (u,v) = u + v | |
- fun addp u v = u + v | |
(* val add : int * int -> int | |
val addp : int -> (int -> int) *) | |
- val addp1 = curry add; | |
val addp1 = fn : int -> int -> int | |
- val add1 = uncurry addp; | |
val add1 = fn : int * int -> int | |
*) | |
fun map f [] = [] (* We could have replaced [] by nil *) | |
| map f (x::xs) = f(x) :: map f xs | |
(* 'a is called a type variable. *) | |
- datatype color = Red | Blue | Green; | |
datatype color = Blue | Green | Red | |
- Blue; Red; Green; | |
val it = Blue : color | |
val it = Red : color | |
val it = Green : color | |
(* Here is a function that takes one of these as argument *) | |
fun say(col) = | |
if col = Red then "You are red!" else | |
if col = Green then "You are green!" else | |
if col = Blue then "You are blue!" else | |
raise Fail "Unknown color" | |
fun say Red = "You are red!" | |
| say Green = "You are green!" | |
| say Blue = "You are blue!" | |
fun evenly_positioned_elems (odd::even::xs) = even::evenly_positioned_elems xs | |
| evenly_positioned_elems [odd] = [] (* Base case: throw away *) | |
| evenly_positioned_elems [] = [] (* Base case *) | |
(* The case expression can also be used to pattern match and return a value *) | |
datatype temp = | |
C of real | |
| F of real | |
fun temp_to_f t = | |
case t of | |
C x => x * (9.0 / 5.0) + 32.0 | |
| F x => x | |
(* Here is a binary tree datatype *) | |
datatype 'a tree = Nil | |
| Node of 'a tree * 'a * 'a tree; | |
fun inorder (Nil) = [] | |
| inorder (Node (left, x, right)) = inorder (left) @ (x :: nil) @ inorder (right); | |
fun rotate (Nil) = Nil | |
| rotate (Node (Nil, x, t)) = Node (Nil, x, t) | |
| rotate (Node (Node (t1, b, t2), a, t3)) = Node (t1, b, Node (t2, a, t3)); | |
A structure is defined as follows: | |
structure Name = struct | |
Definitions | |
end | |
Example: | |
structure foo = struct | |
type t = string | |
val say = fn x => TextIO.print x | |
end | |
foo.say "Hi!\n"; (* Will print Hi! *) | |
Signatures Give the interface of a structure. | |
signature NAME = sig | |
DECLARATIONS | |
end | |
Signatures, example | |
signature bar = sig | |
type t | |
val say : t -> unit | |
end | |
To say that the structure foo implements the signature bar: | |
structure foo:bar = struct | |
type t = string | |
val say = fn x => TextIO.print x | |
val hello = fn () | |
=> TextIO.print "hello/n" | |
end | |
foo.say "hej" | |
is OK, | |
but not foo.hello() as it is not the part of the signature | |
Functors | |
Build structures from structures. | |
functor FunctorName (ParamName : SigName) | |
= struct | |
... | |
end; | |
To make a structure, we do as follows: | |
structure ResultStructure | |
= FunctorName (ArgumentStructure) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment