views:

139

answers:

3

Okay one of my homework problems is to take a list of lists and return the car of each sublist as a list. I have it to where I can print out the values, but it's not a list. To be honest, I have no clue how to output lists. Here's what I got:

(define (car-print alist)
  (if (null? alist)
      (newline)
      (begin
         (write (car (car alist))) (display " ")
  (car-print(cdr alist)))))

This is a cheap way to do it, perhaps some help on actually solving this problem would be much appreciated. Not necessarily the full answer but steps to get there. Thanks.

+1  A: 

My Scheme is a bit rusty. And I have just a dr-scheme interpreter at hand...

You need to consume your list and return just the first element of every sublist.

To create a list you have to use the cons directive, and you don't need to output it, you need to return it as function result (but you should already know it).

If you need to print the result you should separate the computation from the output and resolve the printing issues in a second step.

For building a list you have several construct, the most basic is cons, it takes a generic element (also a list) and prepend it to a list (the null one, also)

(cons 1) => error: cons need two parameters
(cons 1 null) => (list 1)
(cons 1 2) => error: need a value (first parameter) and a list (the second one)
(cons 1 (cons 2 null) => (list 1 2)

Now to your homework. Usually I don't post homework code but, this time I think you are just an hint away from the solution, so there is a possible one

(define (car-list alist)
  (cond
    ((null? alist) null)
    (else (cons (car(car alist)) (car-list (cdr alist))))
  )
)
; tail recursion version usage: (car-acc-list alist null)
(define (car-acc-list alist acc)
  (cond
    ((null? alist) acc)
    (else (car-acc-list (cdr alist) (cons (car(car alist)) acc)))
  )
)

I used cond, instead of if 'cause I think it permits a nicer formatting of your code. His structure is simple: a list of clauses, with the test condition (or else) as car and action to perform if the condition is satisfied as cdr. If action resolve to a value ((null? alist) null) the function return with that value as return value. If recursion is triggered then the function return when the recursion finish.

There are two version of the solution, you should use the stepper/debugger to investigate their differences.

By the way I used drscheme to test the code, it is a wonderful piece of free (lgpl) software. Minor differences are with other scheme environments but the code should be a very basic one and therefore it should run without issues everywhere.

Eineki
Thank you so much for your help. I'm still trying to learn this, so I really don't know scheme just trying to grasp it rapidly for class.
poorStudent
A: 

To design a function, you need to know what your tools are. For lists, you have:

cons : n l -> (n l)
Construct a list out of an element and a list, placing the element n
at the head of the list

car : l -> n
Return the head of the list

cdr : l -> l
Return the tail of the list

You want to write a function firstl that consumes a list of lists and returns a list. Some examples are:

(firstl (list (list 1 2 3) (list 9 2 3) (list 4 7 3))) -> (1 9 4)
(firstl (list (list 1 2 3))) -> (1)
(firstl '()) -> ()

The last example should give you your first clue: if the argument is an empty list, return an empty list.

(define (firstl lol)     ; list-of-lists (no laughing!)
  (if (null? lol)
    '()
    ....    ; more stuff goes here for the recursive "else" clause. Hint: use cons
))
Barry Brown
thank you for this it helped alot.
poorStudent
+1  A: 

You should use map function:

> (define lst '((1 2 3) (4 5 6) (7 8 9)))
;Value: lst
> (map car lst)
;Value: (1 4 7)
Mr.Cat