VansFannel
VansFannel

Reputation: 45921

How can I check if a list is a list of lists?

I'm trying to check if a parameter before use it in a function with racket. This parameter must be a list of lists.

I have tried:

(andmap (lambda (x) (not (and (list? x) (not (pair? x))))) lst)

with:

(define lst '('(a) '(b) '(c)))

But it fails because (pair? '(a)) is true. With pair? I'm trying to avoid (a . 1) dotted pairs because (list? (a . 1)) is also true.

How can I check if a list is a list of lists and doesn't contains dotter pairs?

Upvotes: 1

Views: 1278

Answers (1)

Alexis King
Alexis King

Reputation: 43842

Three things:

  1. To check if a list is a list of lists, you can simply write

    (define (list-of-lists? v)
      (and (list? v) (andmap list? v)))
    

    which first checks if the value is a list, then checks if all its elements are lists.

  2. If you are doing this because a function should only accept a list of lists, and other values are illegal, then you should make things easier for yourself by using Racket’s contract system instead of doing the validation yourself:

    (require racket/contract)
    
    (define/contract (f lst-of-lsts)
      (-> (listof list?) any/c)
      #| do something here |#)
    
  3. You, like many people exposed to it for the first time, seem to have some confusion about how quote works. You probably mean to write '((a) (b) (c)), not '('(a) '(b) '(c)). Please read What is the difference between quote and list?, or just use the list function.

Upvotes: 3

Related Questions