SML: define an array - sml

Forgive me, if it's trivial but
I am reading the documentation of arrays in SML and I am confused . I see many functions but how do I make my own array; How do I initialize one? (Everything , I tried failed)
For example a list is initialised like that :
val l = [1,2,3];
if I wanted [1,2,3] to be an array 1x3 ?
I found how to initialize one array but with only one value like:
array(4,0) (*creates [0,0,0,0] *)
but what about the [1,2,3];

You have (at least) two possibilities for that, either using
Array.fromList:
val a = Array.fromList [1, 2, 3];
either using Array.tabulate:
fun incr x = x + 1;
val a = Array.tabulate (3, incr);
Array.tabulate takes two arguments: the size of your array and a
function used to initialise the items of your array.
val a = Array.tabulate (3, incr);
is thus equivalent to:
val a = Array.fromList [incr(0), incr(1), incr(2)];
Note that I have defined a function incr but I could also have done:
val a = Array.tabulate (3, fn x => x + 1);

Related

How to subtract two consecutive element in a list in Scala?

I would like to subtract two consecutive element in a list with numbers in Scala.
For example : I have this list :
val sortedList = List(4,5,6)
I would like to have an output list like diffList =(1, 1) where 5-4 = 1 and 6-5 = 1.
I tried the following code:
var sortedList = List[Int]()
var diffList = List[Int]()
for (i <- 0 to (sortedList.length - 1) ;j <- i + 1 to sortedList.length - 1)
{
val diff = (sortedList(j) - sortedList(i))
diffList = diffList :+ diff
}
I have the following result for diffList =(1, 2, 1) but I want diffList = (1,1).
It's because of the for loop. it does not iterate over the two variables (i and j) at once.
You do not mutability nor imperative programming to solve this problem, functional programming got you covered.
def consecutiveDifferences(data: List[Int]): List[Int] =
if (data.isEmpty) List.empty
else data.lazyZip(data.tail).map {
case (x, y) => y - x
}
As I always say, the Scaladoc is your friend.
(Also, as an advice, the best way to learn functional programming is to forbid yourself from mutability)
You can use the sliding method, which according to the docs:
/** Groups elements in fixed size blocks by passing a "sliding window"
* over them (as opposed to partitioning them, as is done in `grouped`.)
*
* An empty collection returns an empty iterator, and a non-empty
* collection containing fewer elements than the window size returns
* an iterator that will produce the original collection as its only
* element.
* #see [[scala.collection.Iterator]], method `sliding`
*
* #param size the number of elements per group
* #return An iterator producing ${coll}s of size `size`, except for a
* non-empty collection with less than `size` elements, which
* returns an iterator that produces the source collection itself
* as its only element.
* #example `List().sliding(2) = empty iterator`
* #example `List(1).sliding(2) = Iterator(List(1))`
* #example `List(1, 2).sliding(2) = Iterator(List(1, 2))`
* #example `List(1, 2, 3).sliding(2) = Iterator(List(1, 2), List(2, 3))`
*/
Then, solving your query is pretty straight forward:
diffList = sortedList.sliding(2).collect {
case Seq(a, b) =>
b - a
}.toList
Which results in List(1,1)
Code run at Scastie.
for(i <- 0 until (sortedList.size - 1)) yield sortedList(i + 1) - sortedList(i)
yield Vector(1,1) which can be converted to list with toList
That's can be also achieved with the following function:
val sortedList = List(4,5,7)
#tailrec
def findDiffs(xs: List[Int])(seed: List[Int]): List[Int] = {
if(xs.isEmpty || xs.size == 1) seed.reverse
else {
val currDiff = xs(1) - xs(0)
findDiffs(xs.tail)(currDiff :: seed)
}
}
val res = findDiffs(sortedList)(Nil)
println(res)
Or just easily with zip:
sortedList.drop(1) zip sortedList map { case (x,y) => x - y }
Sliding (see answer by #Tomer Shetah) over a list delivers an iterator, which may prove convenient for very large collections to avoid/reduce the amount of intermediate structures in the processing. Another approach includes the zipping of the list with itself shifted by one (see answers by #Luis Miguel Mejía Suárez and #Zvi Mints); in this regard another approach to shifting and then zipping is by dropping the first element as in
xs.drop(1) zip xs map {case(a,b) => b-a}
This can be generalised by dropping any number n so that we subtract the first and the n-th elements, then the second and the n+1-th elements, and so forth.

SML List [1, 2, 3,...n]

I need to create a list [1,2,3...n] without using pre implemented List fuctions. I can make the list backwards by writing :
fun makeList(x : int) =
if x = 0
then []
else x :: makeList(x-1)
Then I could reverse it and get [1,2,3,4] if inputting 4. How would I do this in only one function?
You've made the reverse list in one function and without using the List library.
To make it in the right order, you can use an accumulating argument:
fun makeList 0 result = result
| makeList n result = makeList (n-1) (n :: result)
Testing this:
- makeList 10 [];
> val it = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] : int list
This function takes an extra argument in which it accumulates the result in the right order.
This is what trips up other correspondents in this Q&A and what has made previous answerers delete their responses: Either you accept that this makeList takes an extra empty list as initial argument, which is kind of messy, or you nest this function inside another function that hides this mechanism:
fun makeList n =
let fun go 0 result = result
| go i result = go (i-1) (i :: result)
in go n [] end
But then you would not have used one function. Unless you mean one exposed function, since the inner function is only available in the context of the definition of makeList. As the problem statement is unclear about this, answering can be unsatisfactory.
Either you make one function, and allow for its type signature to be different (taking an extra argument), or you make one exposed function and allow for it to have an inner function that accumulates the result in reverse.

Printing int -> int list in ocaml

The function 'succ_di_nodo' prints the successors of a given node in a given graph:
type peso = int;;
type 'a grafo = Gr of (int * peso * int) list;;
let g1 = Gr [(1,3,2);(1,9,5);(2,2,3);(5,4,6);(3,1,6);(3,7,4);(6,2,7);(4,4,6)];;
let rec succ_di_nodo (Gr grafo) nodo =
let rec f_ausiliaria = function
[] -> []
| (x,y,z)::coda ->
if x = nodo then z::f_ausiliaria coda
else if z = nodo then x::f_ausiliaria coda
else f_ausiliaria coda in f_ausiliaria grafo;;
g1 is the Graph itself and the value are (node1,weight,node2).
When i pass to the function succ_di_nodo the value for example (succ_di_nodo g1 4) it returns correctly: int list = [3;6].
The question is, when i call the function (succ_di_nodo g1) without giving a specific node it return the type int -> int list; so it is not an empty list and i want to see the exact return value of this function call. How can i print the type int -> int list in Ocaml?
When you call succ_di_nodo with only one argument it returns a function that accepts the second argument and returns the list of successors. This is called partial application.
The int -> int list type denotes a function that takes one argument of type int and returns a value of type int list. You can't print a function value (the default printer will just print <fun>). In order to print a function, you would need to enumerate all values in the input domain, which is usually infinite (or close to that). For testing purposes, you can, of course, apply you function to a set of input values, to see what it outputs, e.g.,
List.init 10 (succ_di_nodo g1);;
will apply (succ_di_nodo g1) to 0, 1, and so on up to 9 and return the result in a list, i.e., the output will be
[[]; [2; 5]; [1; 3]; [2; 6; 4]; [3; 6]; [1; 6]; [5; 3; 7; 4]; [6]; []; []]
You can also trace your function in a toplevel (i.e., when you are running your function in the interpreter), by using the #trace directive. It will show the arguments that go into the function and values that go out. For the sake of experiment try this in the toplevel:
#trace succ_di_nodo;;
(you need to type the leading # it is a part of the directive name). When you will apply succ_di_nodo to two arguments, you will notice that the function first returns a new function, codenamed succ_di_nodo*, which is the result of the application of the first argument, and, finally, the second argument is passed to the returned succ_di_nodo* function. This process is called currying, which is an essential concept in functional programming.
# #trace succ_di_nodo;;
succ_di_nodo is now traced.
# succ_di_nodo g1 0;;
succ_di_nodo <--
Gr
[(1, 3, 2); (1, 9, 5); (2, 2, 3); (5, 4, 6); (3, 1, 6); (3, 7, 4);
(6, 2, 7); (4, 4, 6)]
succ_di_nodo --> <fun>
succ_di_nodo* <-- 0
succ_di_nodo* --> []
- : int list = []
#
When you are done, you can untrace a function with the #untrace directive.

SML adding indices to a list

Given a generic list, return a list containing the same objects in a tuple with their index in the list.
For example:
f ["a", "b"];
- val it = [(0,"a") , (1,"b")] : (int * string) list
The function should be a one-liner, meaning no pattern matching, recursion, if/else, helper functions and let/local. So far i could only make a list of indices given the input list:
fun f lst = List.take((foldl (fn (x,list) => [(hd(list)-1)]#list) [length(lst)] (lst)),length(lst));
f [#"a",#"b"];
- val it = [0, 1]: int List.list;
I should add the list items to these indices in a tuple but i'm not sure how to do that.
Here is a hint for one way to solve it:
1) Using List.sub, create an anonymous function which sends an index i to the pair consisting of i and the lst element at index i.
2) Map this over the result obtained by calling List.tabulate on length lst and the function which sends x to x.
I was able to get this to work (on one line), but the result is ugly compared to a straightforward pattern-matching approach. Other than as a puzzle, I don't see the motivation for disallowing that which makes SML an elegant language.
It appears that i forgot the #i operator to access the i'th element of a tuple. The answer is the following:
fun f xs = List.take((foldr (fn (x,list) => [(#1(hd(list))-1,x)]#list) [(length(xs),hd(xs))] (xs)),length(xs));
f (explode "Hello");
- val it = [(0, #"H"), (1, #"e"), (2, #"l"), (3, #"l"), (4, #"o")]: (int * char) List.list;

Writing multiple functions in SML - Sequential Composition

I would like to understand how sequential composition works much better than I do now in SML. I have to write a program that takes a list of integers and moves the integer at index zero to the last index in the list. ie. [4, 5, 6] -> [5, 6, 4].
The code I have right now is:
- fun cycle3 x =
= if length(x) = 1 then x
= else (List.drop(x, 1);
= x # [hd(x)]);
val cycle3 = fn : 'a list -> 'a list
The question lies in my else statement, what I want to happen is first concatenate the first term to the end, and then second drop the first term. It seems simple enough, I just don't understand how to perform multiple functions in a particular order using SML. My understanding was that the first function called has the scope of the second function that would have the scope of the third function.. etc etc.. What am I doing wrong here?
Most things in SML are immutable -- your function, rather than modifying the list, is building a new list. List.drop(x,1) evaluates to a new list consisting of all but the first element of x, but does not modify x.
To use your method, you would bind the result of List.drop(x,1) to a variable, as in the following:
fun cycle3 x = if length x = 1
then x
else let
val y = List.drop(x,1)
in
y # [hd(x)]
end
Alternately, a cleaner way of doing this same thing, that also handles the possibility of an empty list:
fun cycle3 [] = []
| cycle3 (x::xs) = xs # [x]