0

I am new to SML programming and I have a problem to create a function to remove occurrences of an atom A from a list of integers. This list can be nested to any levels, means we can have list like [1,2,3] and we can have list like [[1,2],[2,3]] as well as list like [[[1,2],[1,2]],[[2,3],[2,3]]].
So my problem is how can I check if the given item is a list or an atom as I have not found any such function in SMLNJ so far?
I have created a function that checks if the list is empty or not and then it calls a helper iterative function to check if the head of the list is a list or an atom. If it's an atom then replace it with another atom and continue with the rest of the tail.

Inside the helper function if I check that tail of the head of list is empty then it gives an error as tail function can have a list only.
So I have to do it like tl([hd(a)), and if I do that, then it will always be empty.
If I apply it on the first list I get head as 1 and wrapping it in [] results in [1], so tail of this will be []. Same way if I get head of second list it will be [1,2] and wrapping it in [] will result in [[1,2]], so tail of this is again []. So is there any way how I can check if the given item is an atom or again a list?

Thanks in advance for all responses.

matthias_h
  • 11,356
  • 9
  • 22
  • 40
  • 2
    You can't check what type something is at run-time - that's already known at compile-time. I have a feeling that you have missed something in the description of this task. – molbdnilo Oct 20 '14 at 13:05
  • Nope that's very much it actually the original problem was in scheme but professor wants us to implement this in SML/NJ so I am out of clues here how to do that. Here is the original scheme problem. Write a Scheme function that takes two atoms and a list as parameters and returns a list identical to the parameter list except all occurrences of the first given atom in the list are replaced with the second given atom, no matter how deeply the first atom is nested. now my goal is to implement this in SML/NJ – Ashish Tyagi Oct 20 '14 at 13:46

2 Answers2

3

"This list can be nested to any levels" is not possible in SML, because it's statically typed, and a list type has a specific element type. You either have an int list, which is a list whose elements are all int, or int list list, which is a list whose elements are all int list. You can't have a mixture.

The closest to what you are talking about would be to make an algebraic datatype with two cases, a leaf, or a nested list of elements of this datatype again. Then you can use pattern matching to deconstruct this datatype.

newacct
  • 119,665
  • 29
  • 163
  • 224
0

As stated in the other answer:

You could define your own data type

datatype 'a AtomList = Atom of 'a | List of 'a AtomList list

Then, with this data type you could define all the atom lists you mentioned above:

val x = List([Atom(1),Atom(2),Atom(3)])
val y = List([List([Atom(1),Atom(2)]),List([Atom(3),Atom(4)])])
val z = List([
        List([
            List([Atom(1),Atom(2)]),
            List([Atom(1),Atom(2)]),
            List([
                List([Atom(2), Atom(3)]),
                List([Atom(2), Atom(3)])
                ])

            ])
        ])

Then to go over your atom list, you would use pattern matching, as in:

fun show xs =
    case xs of
        Atom(x) => (*do something with atom*)
      | List(ys) => (*do something with list of atoms *)   
Edwin Dalorzo
  • 76,803
  • 25
  • 144
  • 205
  • Thanks for explaining this but I have a constraint in my problem that I have to use int list with arbitrary depth. – Ashish Tyagi Oct 19 '14 at 05:40
  • @AshishTyagi What are you talking about? This is already of ant arbitrary depth. I have represented the same examples you gave with are all of different depths. Am I missing something? – Edwin Dalorzo Oct 19 '14 at 13:02
  • That's correct what you have represented is of different depth but what my problem states is I have to use the int list or int list list not atom List or atom List List is there any thing that I can do to still take input as int list or int list list and do the same thing as explained above – Ashish Tyagi Oct 19 '14 at 16:06