SML Basics: 1. Experimenting with basic expressions: Guess the results of each of the following expressions, then type in the expressions and see if you were right. Become especially intrigued by the typing messages. a: "3;" b; "3;4;" b': "val x = 2;" b'': "let val x = 3 in (x=3) end;" c: "x=3;" d: "(3=4) andalso (3 div 0 = 3);" e: "fn x => x+1;" f: "((fn x => x+1) 3);" g: "fun f 0 = 1 | f n = 2*(f (n-1));" h: "f 4;" i: "fun g x y = (g y x);" j: "nil;" k: "1::(2::nil);" l: "[1,2]@[3,4];" m: "[1]::[2,3];" n: "datatype rational = r of int*int;" o: "r(2,3);" After you understand each of the above examples, do the following: 1. Define the data structure "rational" to represent fractions as before: datatype rational = r of int*int; Euclid's algorithm to find the greatest common denominator of two numbers can be written in C as follows: int gcd(int a, int b) { if (b==0) return a; else return gcd(b,(a%b)); } a: Write the function in SML (a%b is "a mod b" in ML). Use pattern matching. b: Using gcd, write a function to reduce fractions represented by the "rational" type. c: Define rational equality, addition, and multiplication. Also define "sign" to determine if the number is positive or negative (0 can be considered positive). Make sure the functions only return reduced fractions. 2. Use the "map," "filter", and "fold" operations to define the following: i: "evens L" - takes a list of integers L and returns only the even numbers. ii: "alleven L" - tests if all numbers in L are even numbers. iii: "binum L" takes a list L of numbers and computes the sum of their respective powers of two. So if L = [0,2,3] then "binum L" should return 13 (1+4+8). Negative numbers should be ignored.