0

I just start working with standard ml and really have some trouble understanding the list in this language. So my question is how to shorten a list in ml ? For example, if I have a list [1,2,3,4,5,6], I want to shorten it to [1,2]. What I'm having so far is:

fun shorten(i, l) = let val newlen = i in newlen = length l//in correct

what I want is a function that will take i as a location that user want to shorten the list and l is the list. In this case, the input should look like shorten(2, [1,2,3,4,5,6] and the output should look like [1,2]

user4075830
  • 87
  • 1
  • 2
  • 11
  • Instead of writing random code, what ideas do you have that could be conducive to writing a correct solution? – isekaijin Oct 27 '14 at 06:55
  • The one that I write above is what I got so far, what im trying to do is to create a variable newlen which equal to i and set it equal to the new length of the list. I'm a beginner with ml so I kinda lost here. – user4075830 Oct 27 '14 at 07:51

2 Answers2

1

This function should do it:

fun shorten(_, nil) = nil
  | shorten(0, _) = nil
  | shorten(i, x::xs) = x::shorten(i - 1, xs)

As you noticed, this function doesn't throw any exceptions when i is larger than the length of the list. An approach that uses exceptions would be this:

exception IllegalArgument

fun shorten(_, nil) = nil
  | shorten(0, _) = nil
  | shorten(i, x::xs) =
    if i > length(x::xs) then raise IllegalArgument
    else x::shorten(i - 1, xs)

In SML you need to declare any exception type with exception before it is raised using raise. Otherwise, the exception type is not bound in the environment and the interpreter will complain about the symbol being unknown.

  • Thank you. May I ask how to check for error with this case ? what I have: `fun shorten(_, nil) = raise Error | shorten(0, _) = raise Error | shorten(i, x::xs) = if i > length (x::xs) then raise Error else x::revert((i - 1), xs)<html>` doesnt seem to be working – user4075830 Oct 27 '14 at 23:46
1

The SML Basis Library contains the function List.take to perform the required task as part of the List Structure.

- fun shorten ( toHowMany, myList ) =  List.take ( myList, toHowMany ) ;
val shorten = fn : int * 'a list -> 'a list

- shorten ( 2, [1,2,3,4,5,6] ) ;
val it = [1,2] : int list

If the order of the arguments doesn't matter, then List.take can be used directly:

- List.take ( [1,2,3,4], 2 ) ;
val it = [1,2] : int list
ben rudgers
  • 3,647
  • 2
  • 20
  • 32