0
votes

if am trying to write a simple function that list of pair of integers - representing a graph and returns a list of integers : all the nodes in a graph eg if input is [(1,2) (3,4) (5,6) (1,5)] o/p should be [1,2,3,4,5,6,1,5] The function is simply returning list of nodes , in the returning list values may repeat as above. I wrote the following function

fun listofnodes ((x:int,y:int)::xs) = if xs=nil then [x::y] else [[x::y]@listofnodes(xs)]

stdIn:15.12-15.18 Error: operator and operand don't agree [tycon mismatch operator domain: int * int list operand: int * int in expression: x :: y.

I am not able to figure out what is wrong.

1

1 Answers

1
votes

first of all you should know what each operator does: :: puts individual elemtents into an existing list so that: 1::2::3::[] = [1,2,3] @ puts two lists together so that: [1,2] @ [3,4] = [1,2,3,4]

you can also use :: to put lists together but then it becomes a list of lists like: [1,2] :: [3,4] = [[1,2],[3,4]]

so by writing [x::y] you are saying that x and y should become a list inside a list.

and you shouldnt use an if statement to check for the end of the list, instead you can use patterns to do it like this:

fun listofnodes [] = []
  | listofnodes ((x,y)::xs) = x :: y :: listofnodes(xs);

the first pattern assures that when we reach the end of the list, when you extract the final tuple your xs is bound to an empty list which it calls itself with, it leaves an empty list to put all the elements into, so that [(1,2) (3,4) (5,6) (1,5)] would evaluate like this:

1 :: 2 :: 3 :: 4 :: 5 :: 6 :: 1 :: 5 :: [] = [1,2,3,4,5,6,1,5].

you could also make it like this:

fun listofnodes [] = []
  | listofnodes ((x,y)::xs) = [x,y] @ listofnodes(xs);

this way you make a small 2 element list out of each tuple, and then merge all these small lists into one big list. you dont really need the empty list at the end, but its the only way of ensuring that the recursion stops at the end of the list and you have to put something on the other side of the equals sign. it evaluates like this:

[1,2] @ [3,4] @ [5,6] @ [1,5] @ [] = [1,2,3,4,5,6,1,5].

also you cast your x and y as ints, but you dont really have to. if you dont, it gets the types " ('a * 'a) list -> 'a list " which just means that it works for all input types including ints (as long as the tuple doesnt contain conflicting types, like a char and an int). im guessing you know this, but in case you dont: what you call pairs, (1,2), is called tuples.