How do i convert an array type to a list type in sml. I have searched the list and array structure functions but have not found one that does this (there is a list to array function though).
Description of List structure:
http://sml-family.org/Basis/list.html
Description of Array structure:
http://sml-family.org/Basis/array.html
While there isn't a built in direct conversion function, you could use Array.foldr to quite easily construct a corresponding list:
fun arrayToList arr = Array.foldr (op ::) [] arr
Example:
- val arr = Array.fromList [6, 3, 5, 7];
val arr = [|6,3,5,7|] : int array
- val ls = arrayToList arr;
val ls = [6,3,5,7] : int list
There doesn't seem to be a built-in List.fromArray or Array.toList. It looks like the easiest way to define it would be
List.tabulate(Array.length(arr), fn i => Array.sub(arr, i))
So...
Standard ML of New Jersey v110.76 [built: Thu Feb 19 00:37:13 2015]
- val arr = Array.fromList([1, 2, 3, 4, 5]) ;;
[autoloading]
[library $SMLNJ-BASIS/basis.cm is stable]
[autoloading done]
val arr = [|1,2,3,4,5|] : int array
- fun listFromArray arr = List.tabulate(Array.length(arr), fn i => Array.sub(arr, i)) ;;
[autoloading]
[autoloading done]
val listFromArray = fn : 'a array -> 'a list
- listFromArray(arr) ;;
val it = [1,2,3,4,5] : int list
-
Related
I currently have a list that contains other lists inside. [ [1, 2, 3]; [9, 8, 7];...]
I would like to create a list of tuples from two indices in one of these 3 element lists I have stored inside of the entire list.
I have written something like
let makeTuple list =
let rec tuple list tuplesList =
match list with
| [] -> ()
| h::t -> (tuple t ( (List.item 2 list, List.item 5 list)::tuplesList))
tuple list []
When I run this function, it is giving me an error that there is an out of range index. I've tried other options but I can't seem to make sense of any of them. I'm new to F-sharp :-S. Any tips would be great.
It's not 100% clear what output you are expecting. But this revision at least runs and returns a list of tuples, so maybe it is close to what you want.
let makeTuple list =
let rec tuple list tuplesList =
match list with
| [] -> tuplesList
| h::t -> (tuple t ( (List.item 0 h, List.item 2 h)::tuplesList))
tuple list []
let lst = [ [1; 2; 3]; [9; 8; 7]; [14; 15; 16]]
lst |> makeTuple
Output:
val makeTuple : list:'a list list -> ('a * 'a) list
val lst : int list list = [[1; 2; 3]; [9; 8; 7]; [14; 15; 16]]
val it : (int * int) list = [(14, 16); (9, 7); (1, 3)]
I am very new to SML/NJ and I am kind of lost. I have been trying to implement a function that is going to search through the list of tuples that have some lists in it, for example:
val x = [(5, 2, [9 , 8, 7]), (3, 4, [6, 5, 0]), (11, 12, [8, 3, 1])]
I would like my function to add the first element of the tuple to the new list once there is a match between my target number and a number in element 3 of the tuple. I have tried several implementations, but none of them work properly so far.
type id = int* int* int list;
val b:id list = [(5,2,[9,8,7]), (3,4,[6,5,0]), (11, 12, [8,3,1])]
val number: int = 8;
val a: int list = nil;
fun findNum(nil) = a | findNum (x: id list) =
let val tem = hd(x)
val theList = #3tem
val i = #1tem
fun findMatch(nil) = a | findMatch(tem) =
if (number = hd(theList)) then i::a
else findMatch (tl(theList))
in findNum(tl(x))
end;
findNum(b);
I know it is badly written, and that is why it keeps returning an empty list. I feel like I need to do "if else" instead of let/in/end so it will recursively call the rest of the tuples in the list. My problem is that I am not sure how to do it because if I use if/else then I cannot declare some value inside the function. I appreciate any suggestions or hints.
Thank you.
You might start with a function member (x, xs) that is true if x is an element in the list xs:
fun member (x, xs) = List.exists (fn y => x = y) xs
A base case is when the list of three-tuples is empty. Then x does not occur in the third element of any of the (non-existing) three-tuples, and the list of results is empty. A recursive case is achieved by pattern matching against the first element of the list being a three-tuple, (i,j,xs), and the tail of the list, ts, and ask if x is a member of that third element xs; if it is, return the first part of the tuple, i:
fun find (x, []) = []
| find (x, (i,j,xs)::ts) =
if member (x, xs)
then i :: find (x, ts)
else find (x, ts)
A shorter version using the higher-order list combinators map and filter:
fun find (x, ts) = map #1 (filter (fn (i,j,xs) => member (x, xs)) ts)
Here is my implementation with some slight changes:
type id = int* int* int list;
val b:id list = [(5,2,[9,8,7]), (3,4,[6,5,0]), (11, 12, [8,3,1])]
val number: int = 8;
fun findNum [] = []
| findNum (x::xs) =
let
val theList :int list = #3 (x :id)
val i : int = #1 x
fun findMatch [] = false
| findMatch (y::ys) = if (number = y) then true
else findMatch ys
in
if (findMatch theList = true) then i ::(findNum xs)
else (findNum xs)
end;
Example:
- findNum b;
val it = [5,11] : int list
I have a list (size of the list is variable):
val ids = List(7, 8, 9)
and would like to get the following map:
val result= Map("foo:7:bar" -> "val1",
"foo:8:bar" -> "val1",
"foo:9:bar" -> "val1")
everything in the map is hard-coded except ids and value is the same for everyone, but map has to be mutable, I'd like to update one of its values later:
result("foo:8:bar") = "val2"
val result= Map("foo:7:bar" -> "val1",
"foo:8:bar" -> "val2",
"foo:9:bar" -> "val1")
You can do that like this: First map over the list to produce a list of tuples, then call toMap on the result which will make an immutable Map out of the tuples:
val m = ids.map(id => ("foo:" + id + ":bar", "val1")).toMap
Then convert the immutable Map to a mutable Map, for example like explained here:
val mm = collection.mutable.Map(m.toSeq: _*)
edit - the intermediate immutable Map is not necessary as the commenters noticed, you can also do this:
val mm = collection.mutable.Map(ids.map(id => ("foo:" + id + ":bar", "val1")): _*)
Try this:
import scala.collection.mutable
val ids = List(7, 8, 9)
val m = mutable.Map[String, String]()
ids.foreach { id => m.update(s"foo:$id:bar", "val1") }
scala> m
Map(foo:9:bar -> val1, foo:7:bar -> val1, foo:8:bar -> val1)
You, don't need to create any intermediate objects, that map does.
Why not use foldLeft?
ids.foldLeft(mutable.Map.empty[String, String]) { (m, i) =>
m += (s"foo:$i:bar" -> "val1")
}
Try Like this:
scala> import scala.collection.mutable
scala> val result = mutable.Map[String, String]()
result: scala.collection.mutable.Map[String,String] = Map()
scala> val ids = List(7, 8, 9)
ids: List[Int] = List(7, 8, 9)
scala> for(x <- ids){
| result("foo:%d:bar".format(x)) = "val1"
| }
scala> result
res3: scala.collection.mutable.Map[String,String] = Map(foo:9:bar -> val1, foo:7:bar -> val1, foo:8:bar -> val1)
Lets take an example where store is my class.
class store(val a:Int) { }
In the code i want to create a list of store.
val list : List[store] = new List[store]()
How can i add a store in the same list?
First off, it's usually a good idea to capitalize your class names.
scala> class Store(val a:Int) { }
defined class Store
scala> val list : List[Store] = List.empty
list: List[Store] = List()
scala> val newList = new Store(4) :: list
newList: List[Store] = List(Store#243306de)
Your list is, by default, immutable so you'll have a new list every time an element is added.
scala> val newerList = new Store(71) :: newList
newerList: List[Store] = List(Store#30f57af0, Store#243306de)
ADDENDUM
If you need a mutable list (not usually recommended) you could try the following.
scala> import scala.collection.mutable.MutableList
import scala.collection.mutable.MutableList
scala> val myList: MutableList[Store] = MutableList.empty
myList: scala.collection.mutable.MutableList[Store] = MutableList()
scala> myList += new Store(56)
res322: myList.type = MutableList(Store#6421614e)
scala> myList += new Store(29)
res323: myList.type = MutableList(Store#6421614e, Store#85b26)
scala> myList += new Store(11)
res324: myList.type = MutableList(Store#6421614e, Store#85b26, Store#5d2f7883)
Mutable variables are considered poor style and an impediment to proper Functional Programming.
To add element to the beginning of the list use :: :
val l = List(1, 2, 3)
val l1 = 5 :: l // List(5, 1, 2, 3)
or
val l1 = l.::(5)
To add element to the end of the list use :+ :
val l2 = l :+ 5 // List(1, 2, 3, 5)
So, to add store object to the end of the list (though it is not efficient), write this:
val s = new Store(1)
val newList = list :+ s // list is immutable
I have made the function fun charListToInt (y) = map (fn x => Char.ord (x) - 64) y::[] that takes a char list and returns a int list list with the integer code of the character (A = 1, B = 2, C = 3...).
For example: charListToInt [#"A", #"B", #"C", #"D", #"E"] = [[1, 2, 3, 4, 5]].
What I really want to do is to give the function the type val charListToInt = fn : char list list -> int list list instead of just having char list as input, like this:
[[#"A", #"B"], [#"C", #"D"]] = [[1, 2], [3, 4]]
Can this really be done by using the map-function?
val charListListToIntListList = map (map (fn c => ord c - ord #"A" + 1))