Defining a function that accepts a List of Lists in racket - racket

My assignment is to count how many lists I have with length 3 in my list (List of List).
I thought I built everything correctly, but when I want to send the first list to my recursive function it fails because my list has the type Any, and I can't find a way to make it a list of lists.
#lang pl
(: count-3lists : (Listof Any) -> Number)
(define (count-3lists l)
(cond
[(null? l) 0]
[else (+ (count-3lists-helper (first l)) (count-3lists (rest l)))]))
(: count-3lists-helper : (Listof Any) -> Number)
(define (count-3lists-helper l)
(cond [(= (length l) 3) 1]
[else 0]))
(: length : (Listof Any) -> Number)
(define (length l)
(cond
[(null? l) 0]
[else (add1 (length (rest l)))]))
The error I get is:
. Type Checker: Polymorphic function `first' could not be applied to
arguments:
Types: (Pairof a (Listof b)) -> (a : ((! False # (car) (0 0)) | (False # (car) (0 0))) : (car (0 0)))
(Listof a) -> a
Arguments: (Pairof Any (Listof Any))
Expected result: (Listof Any)
in: (first l)

It seems like you want your count-3lists function to take a list of lists as its input. Right now you have (Listof Any).
What you want is express something like (Listof List), but the inner list has to be a list of something, so you can write that as (Listof (Listof Any)).
Then the first part of your code becomes this:
(: count-3lists : (Listof (Listof Any)) -> Number)
(define (count-3lists l)
(cond
[(null? l) 0]
[else (+ (count-3lists-helper (first l)) (count-3lists (rest l)))]))
After that, the rest of your code works. It turns out that your length function was fine. (So you should probably rename your question.)

Related

Going over a list of strings to find the string with the needed prefix

I need to define the function plPrefixContained – that consumes 5 strings and
returns the first one that contains the string "pl" as a prefix – if one such
exists, and returns #f otherwise.
What I'm trying to do is to use the prefixes function to go over all the strings in the list and check their prefixes, put them in a new list and to output the first string as the result.
(I will handle the #f case later) my code is down below but it keeps giving me the error-
first: contract violation
expected: (and/c list? (not/c empty?))
given: '()
any help would be appreciated
(: plPrefixContained : String String String String String -> String)
(define (plPrefixContained x y z w v)
(list-ref (prefixes (list x y z w v) '()) 0))
(: prefixes : (Listof String) (Listof String) -> (Listof String))
(define (prefixes lis em)
(cond
[(and (eq? (string-ref (first lis) 0) "p") (eq? (string-ref (first lis) 1) "l"))
(cons (first lis) em)]
[else
(prefixes (rest lis) em)]))
this is how I want my output to be like-for example
(test (plPrefixContained "yypl" "opl" "lpTT" "plpl" "lol")
=>
"plpl")
There are two problems:
intensional equality eq?, instead of extensional equality such as equal? or string=?
comparing string / char, instead of comparing char / char or string / string
You are using eq?, which always makes me suspicious. eq? uses "intensional" equality, which is basically pointer equality, meaning that a string which is allocated somewhere in memory won't necessarily be eq? even if it has the same characters. You can see this with (eq? "abc123" (string-append "abc" "123")).
If you're dealing with strings, lists, or any other data which "contains" things, you should avoid eq?. Instead you should use an "extensional" equality predicate such as equal?, or even better, a predicate specific to the types of values you expect, such as string=?. Here's how they behave better than eq?:
> (eq? "abc123" (string-append "abc" "123"))
#f
> (equal? "abc123" (string-append "abc" "123"))
#t
> (string=? "abc123" (string-append "abc" "123"))
#t
Since you're comparing using the strings "p" and "l", I should be able to substitute eq? with string=? in your code:
(: prefixes : (Listof String) (Listof String) -> (Listof String))
(define (prefixes lis em)
(cond
[(and (string=? (string-ref (first lis) 0) "p") (string=? (string-ref (first lis) 1) "l"))
(cons (first lis) em)]
[else
(prefixes (rest lis) em)]))
However, this reveals the second problem, which I only spotted after seeing the error message:
string=?: contract violation
expected: string?
given: #\y
argument position: 1st
other arguments...:
"p"
The string=? isn't working because its first argument, the result of string-ref, is a character (like #\y), not a string. To fix this, use char=? instead of string=?, and compare with the characters #\p and #\l instead of the strings "p" and "l".
(: prefixes : (Listof String) (Listof String) -> (Listof String))
(define (prefixes lis em)
(cond
[(and (char=? (string-ref (first lis) 0) #\p) (char=? (string-ref (first lis) 1) #\l))
(cons (first lis) em)]
[else
(prefixes (rest lis) em)]))

How the map function implemeted in racket

How does the map function implemented in racket and why, recursion or iteration.
Maybe some implementation example
How to implement map
The map function walks a list (or multiple lists), and applies a given function to every value of a list. For example mappiing add1 to a list results in:
> (map add1 '(1 2 3 4))
'(2 3 4 5)
As such, you can implement map as a recursive function:
(define (map func lst)
(if (empty? lst)
'()
(cons (func (first lst)) (map func (rest lst)))))
Of course, map can accept any number of arguments, with each element passed to the given prop. For example, you can zip two lists together using map list:
> (map list '(1 2 3) '(a b c))
'((1 a) (2 b) (3 c))
To implement this variable arity map, we need to make use of the apply function:
(define (map proc lst . lst*)
(if (empty? lst)
'()
(cons (apply proc (first lst) (map first lst*))
(apply map proc (rest lst) (map rest lst*)))))
Now, this does assume all of the given lists have the same length, otherwise you will get some unexpected behavior. To do that right you would want to run empty? on all lists, not just the first one. But...when you use it, you get:
> (map list '(a b c) '(1 2 3))
'((a 1) (b 2) (c 3))
Note that map here calls itself recursively 3 times. A faster implementation might do some unrolling to run faster. A better implementation would also do proper error checking, which I have elided for this example.
How Racket's map is implemented
If you open up DrRacket (using the latest Racket 7 nightly) and make the following file:
#lang racket
map
You can now right click on map and select Open Defining File. From here, you can see that map is renamed from the definition map2. The definition of which is:
(define map2
(let ([map
(case-lambda
[(f l)
(if (or-unsafe (and (procedure? f)
(procedure-arity-includes? f 1)
(list? l)))
(let loop ([l l])
(cond
[(null? l) null]
[else
(let ([r (cdr l)]) ; so `l` is not necessarily retained during `f`
(cons (f (car l)) (loop r)))]))
(gen-map f (list l)))]
[(f l1 l2)
(if (or-unsafe
(and (procedure? f)
(procedure-arity-includes? f 2)
(list? l1)
(list? l2)
(= (length l1) (length l2))))
(let loop ([l1 l1] [l2 l2])
(cond
[(null? l1) null]
[else
(let ([r1 (cdr l1)]
[r2 (cdr l2)])
(cons (f (car l1) (car l2))
(loop r1 r2)))]))
(gen-map f (list l1 l2)))]
[(f l . args) (gen-map f (cons l args))])])
map))

Could not undersand racket function

My proffesor gave us this function:
(: every? : (All (A) (A -> Boolean) (Listof A) -> Boolean))
(define (every? pred lst)
(or (null? lst)
(and (pred (first lst))
(every? pred (rest lst)))))
I couldn't understand the meaning of: All (A) (A -> Boolean).
please can someone can explain to me - what is the meaning of the variable, what the function get, what is it do and what is it return because i can't figure it out.
Let's give the function every? a spin at the repl:
> (every? even? (list 1 2 3 4))
#f
> (every? char? (list #\a #\b #\c))
#t
Note that the type of the first list (list 1 2 3 4) is (Listof Number).
The type of the second list (list #\a #\b #\c) is (Listof Char).
What type should the lst argument of every? have?
Clearly it needs to be a list, but what type are the elements?
We don't know, so we make it a (Listof A), where A stands
for some (unknown) type.
However the predicate pred is called on the elements in the list,
so the type must match. In the first example: even? has the type
"function from number to boolean" aka (A -> Boolean).
In general we need the type: (A -> Boolean) for the predicate.
This becomes:
(: every? : (All (A) (A -> Boolean) (Listof A) -> Boolean))

How to fix the return value in this typed racket code?

(: test (All (A) (-> A A (Rec Expr (Listof (U A Expr))) (Rec Expr (Listof (U A Expr))))))
(define (test new old expr)
(if (null? expr)
expr
(if (list? (car expr))
expr ; <- get error here
expr)))
get error
Type Checker: type mismatch
expected: (Rec g161252 (Listof (U A g161252)))
given: (Pairof
(U (Rec g161259 (Listof (U A g161259))) (Pairof Any (Listof Any)))
(Listof (U A (Rec g161268 (Listof (U A g161268)))))) in: expr
The code return exactly the same expr as the input one.
(define (test new old expr)
(if (and (not (null? expr)) (list? (car expr)))
expr ; <- also get the error
expr))
But
(define (test new old expr)
(if (and (list? (car expr)) (not (null? expr)))
expr ; <- this works fine
expr))
If the logic is in this order, then it works fine.
So why the type checker get the type mismatch error?
The problem with the original code is that expr is "not polymorphic enough". The query (list? (car expr)) changes the type of expr to something incompatible with the polymorphic A.
(It seems to me that you're trying to discriminate between an A and a nested Expr, but typed racket sees list? and refines the type of A. I think!)
Here's another function that's not polymorphic enough.
(: id (All (A) (-> A A)))
(define (id x)
(if (boolean? x) x x))
Fixes
If you're on an older version of Racket (v6.2) you can sneak around this with an alias, but that's not a nice thing to do.
(: id (All (A) (-> A A)))
(define (id x)
(define x2 x)
(if (boolean? x) x2 x)))
You can use list-ref instead of car, because list-ref doesn't allow predicates to affect its argument.
...
(if (list? (list-ref expr 0))
expr
expr)))
Change your types a little, so there's a clear way to tell apart A from Expr.
(: test (All (A) (-> A A (Rec Expr (Listof (U (Boxof A) Expr))) (Rec Expr (Listof (U (Boxof A) Expr))))))
(define (test new old expr)
(if (null? expr)
expr
(if (not (box? (car expr)))
expr
expr)))
Stop using Typed Racket's polymorphism -- it's too clumsy!
The order issue is because and applies predicates in order, and these predicates destructively change an expression's type. So testing (not (null? expr)) after you've checked (list? (car expr)) forgets that you ever did the first check.
Here's more code with the same issue. We ought to know that expr is non-null and has a list at its head, but Typed Racket's forgotten.
(: test2 (-> (Listof (U (List Natural) Boolean)) Boolean))
(define (test2 expr)
(if (and (list? (car expr)) (not (null? expr)))
(= 1 (car (car expr)))
#f))
This is probably a bug.

my "lisp-pl language" throwing mistakes

Cheers!!! i have a question about a function contract that i need to write in the pl language (a lisp contribution ) the contract suppose to have a (list of type A)(list of type b) and return a list of lists (type A B) simultaneously . this is what i got so far but it doesn't work :
(: zip2 : (All (A B) (Listof A) (Listof B) -> (Listof (list A B))))
(define (zip2 listA listB)
(cond [(null? listA) (list (null null))]
[else (list ((car listA) (car listB)))])
(zip2 ((rest listA) (rest listB))))
(equal? (list (list 1 'a) (list 2 'b) (list 3 'c)) (zip2 (list 1 2 3) (list 'a 'b 'c)))
(define (zip2 listA listB)
(cond [(null? listA) null]
[else (cons (list (car listA) (car listB))
(zip2 (rest listA) (rest listB)))]))
Probably the simplest approach is just to use mapping. [Since you are using define I'll assume you are using Scheme].
(define (zip A B) (map list A B))
If you can't use map, then here is a tail-recursive algorithm:
(define (zip A B)
(let zipping ((a A) (b B) (rslt '())
(if (or (null? a) (null? b))
(reverse rslt)
(zipping (cdr a) (cdr b)
(cons (list (car a) (car b)) rslt)))))