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?
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"
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"]
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"
.
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"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With