I am trying to create a function that accepts a number and then produces text they can temporarily copy into their paper as a space saver. Here are a few examples below:
(define
CITATION-SPACE-2
(string-append
"[1] author information\n"
"title information\n"
"venue information\n"
"year & page information\n"
"[2] author information\n"
"title information\n"
"venue information\n"
"year & page information"))
(define
CITATION-SPACE-3
(string-append
"[1] author information\n"
"title information\n"
"venue information\n"
"year & page information\n"
"[2] author information\n"
"title information\n"
"venue information\n"
"year & page information\n"
"[3] author information\n"
"title information\n"
"venue information\n"
"year & page information"))
(check-expect (citation-space 2) CITATION-SPACE-2)
(check-expect (citation-space 3) CITATION-SPACE-3)
I have been able to define the function using cond and string-append but can't figure out how to have a \n between each line of the result (though not after the last line). Also, I am unsure how to define and simplify the function using the foldr list abstraction.
This is what I have tried so far:
(define (citation-space num)
(local [; data-string : Nat -> String
; produces a space saver
; for a supplied number
(define (data-string num)
(foldl (λ (s1 s2)
(string-append s2 "\n" s1))
(string-append
"[" (number->string num) "]"
" author information")
(list "title information"
"venue information"
"year & page information")))]
(cond
[(zero? num) ""]
[(= num 1) (data-string 1)]
[else (string-append
(citation-space (sub1 num))
"\n"
(data-string num))])))
If you didn't have to do this exercise in ISL, you could use string-join
provided by racket/string
.
If you didn't have to use foldl
or foldr
, you could write something like this:
(define (my-join strs sep)
(cond ((null? strs) "")
((= (length strs) 1) (first strs))
(else (string-append (first strs)
sep
(my-join (rest strs) sep)))))
But I think it's possible to solve this problem also with pair of foldl
. Used language is Intermediate Student with Lambda:
(define
CITATION-SPACE-2
(string-append
"[1] author information\n"
"title information\n"
"venue information\n"
"year & page information\n"
"[2] author information\n"
"title information\n"
"venue information\n"
"year & page information"))
(define
CITATION-SPACE-3
(string-append
"[1] author information\n"
"title information\n"
"venue information\n"
"year & page information\n"
"[2] author information\n"
"title information\n"
"venue information\n"
"year & page information\n"
"[3] author information\n"
"title information\n"
"venue information\n"
"year & page information"))
(define (data-string number)
(foldl (lambda (s result)
(string-append result "\n" s))
(format "[~a] author information" number)
(list "title information"
"venue information"
"year & page information")))
(define (citation-space number)
(if (zero? number) ""
(let ((strs (map data-string (range 1 (add1 number) 1))))
(foldl (lambda (s result) (string-append result "\n" s))
(first strs)
(rest strs)))))
(check-expect (citation-space 2) CITATION-SPACE-2)
(check-expect (citation-space 3) CITATION-SPACE-3)
EDIT: Solution with one foldl
:
(define (data-string number)
(foldl (lambda (s result)
(string-append result "\n" s))
(format "[~a] author information" number)
(list "title information"
"venue information"
"year & page information")))
(define (citation-space num)
(cond
[(zero? num) ""]
[(= num 1) (data-string 1)]
[else (string-append
(citation-space (sub1 num))
"\n"
(data-string num))]))