Search code examples
smlnj

SML: How to separate a list into a tuple of 2 lists?


So, I am trying to solve this question which says,

write a function to take the next word off a list of characters. The function returns a tuple of the word as a list of characters and the rest of the list.

e.g. next [#”t”,#”h”,#”e”,#” “,#”c”,#”a”,#”t”] ==> ([#”t”,#”h”,#”e”],[#” “,#”c”,#”a”,#”t”,#” “….]) : char list * char list

• if the list is empty, return a tuple of two empty lists

• if the list starts with a non-letter, return a tuple of the empty list and the list

• otherwise, take the rest of the next word from the tail of the list returning a tuple of the rest of the next word and the rest of the tail of the list, put the head of the original list, which is the head of the word, onto the front of the rest of the word, and return the whole word list and the rest of the tail of the list

• Hint: use a let with a tuple pattern to match the tuple for the rest of word and rest of tail of list

My Approach so far: - fun next [] = ([],[]) | next (x::xs) = if x = chr 32 then ([],(x::xs)) else ???


Solution

  • I know it is a bit late and I'm not sure if I understand it correctly, but this looks fine to me:

    fun next [] = ([], [])
      | next (hd :: tl) =
        if Char.isAlpha hd
        then
            let val (lst1, lst2) = next tl
            in (hd :: lst1, lst2)
            end
        else ([], hd :: tl)
    

    Given example seems to work correctly:

    - next (String.explode "the cat");
    val it = ([#"t",#"h",#"e"],[#" ",#"c",#"a",#"t"]) : char list * char list
    

    It keeps separating head of the list until it gets to the end of the first word. Then it starts to collect these heads into the first list of the tuple. Hope it helped.

    Regards, Špela