Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you manipulate a list of tuples in SML?

Tags:

sml

I'm new to SML, and I was wondering how to get an element in a list of tuples. For example, in the list [("abc", 4), ("def", 6)], how could you extract "abc"? I've tried

x::xs => #1(x)

but I keep getting "unresolved flex record". Any suggestions?

like image 408
Breya Avatar asked Sep 20 '10 20:09

Breya


4 Answers

The error you were having is because things like #1 are kind of special and its type depends on what it is used on. For example, in #1 (1,2), the type of #1 is 'a * 'b -> 'a; whereas in #1 (1,2,3), the type of #1 is 'a * 'b * 'c -> 'a. There is no type like 'a * ... -> 'a that will work for everything, so the compiler has to be able to figure out the type it will be used on (basically, how many elements are in the tuple).

So this doesn't work:

fun f lst =
  case lst of x::xs => #1 x
            | [] => "The list is empty"

because it just knows that it's "some kind of list", and x is "some value of some type". But it doesn't know what kind of tuple it is.

Simply adding a type guard, or some other context that allows the compiler to tell what kind of tuple it is, will work:

fun f (lst : (string * 'a) list) =
  case lst of x::xs => #1 x
            | [] => "The list is empty"
like image 160
newacct Avatar answered Nov 11 '22 00:11

newacct


i would extract it like this:

fun foo ((x,y)::xs) = x;

so that you extract the tuple from the list and bind x to abc and y to 4, and then just return x. like that you can also merge the tuples and get back a list of only strings:

fun f [] = [] 
  | f ((x,y)::xs) = x ^ Int.toString(y) :: f(xs);

would, given the list [("abc",4),(def",6)], return the list ["abc4","def6"]

like image 42
Gnurgen Avatar answered Nov 11 '22 01:11

Gnurgen


You can just extract it using pattern matching.

let
  val lst = [("abc", 4), ("def", 6)]
in
  case lst of (str,_)::xs => str
              | [] => "The list is empty"
end

Will return "abc".

like image 2
sepp2k Avatar answered Nov 11 '22 00:11

sepp2k


you can have a function for getting a tuple value, like:

fun getname(name:string, x:int) = name;

if you have the list:

val lst = [("abc", 4), ("def", 6)]

then, you can extract the name of the first tuple (hd) by doing:

getname(hd lst)

Will return "abc"

like image 1
Jaider Avatar answered Nov 10 '22 23:11

Jaider