|
|
@@ -9,39 +9,49 @@ |
|
|
|
(import srfi-14) |
|
|
|
(import (chicken condition)) |
|
|
|
|
|
|
|
(: curry (procedure * --> procedure)) |
|
|
|
(define (curry fn a) |
|
|
|
(lambda (b) |
|
|
|
(fn a b))) |
|
|
|
|
|
|
|
(: curry2 (procedure * * --> procedure)) |
|
|
|
(define (curry2 fn a b) |
|
|
|
(lambda (c) |
|
|
|
(fn a b c))) |
|
|
|
|
|
|
|
(: perhaps (procedure * -> *)) |
|
|
|
(define (perhaps fn a) |
|
|
|
(if a (fn a) a)) |
|
|
|
|
|
|
|
(: upon ((* -> boolean) procedure * -> *)) |
|
|
|
(define (upon pred? fn a) |
|
|
|
(if (pred? a) |
|
|
|
(fn a) |
|
|
|
a)) |
|
|
|
(if (pred? a) (fn a) a)) |
|
|
|
|
|
|
|
(: member? (* list --> boolean)) |
|
|
|
(define (member? a ln) |
|
|
|
(if (member a ln) #t #f)) |
|
|
|
|
|
|
|
(: default ('a 'b --> (or 'a 'b))) |
|
|
|
(define (default b a) |
|
|
|
(if a a b)) |
|
|
|
|
|
|
|
(define-type association-list (list-of pair)) |
|
|
|
|
|
|
|
;;; Return the value for a given key in an association list, or #f if it doesn't exist. |
|
|
|
(: value (* association-list --> *)) |
|
|
|
(define value |
|
|
|
(compose (curry perhaps cdr) assoc)) |
|
|
|
|
|
|
|
;;; Return the value for a given key in an association list, or a default value if it doesn't exist. |
|
|
|
(: value-with-default (* * association-list --> *)) |
|
|
|
(define (value-with-default k v ln) |
|
|
|
(default v (value k ln))) |
|
|
|
|
|
|
|
(: has-key? (* association-list --> boolean)) |
|
|
|
(define (has-key? k ln) |
|
|
|
(member? k (map car ln))) |
|
|
|
|
|
|
|
(: sort (('a 'a -> boolean) (list-of 'a) --> (list-of 'a))) |
|
|
|
(define (sort less-than? ln) |
|
|
|
(if (<= (length ln) 1) |
|
|
|
ln |
|
|
@@ -50,14 +60,17 @@ |
|
|
|
(sort less-than? (filter (curry less-than? (car ln)) (cdr ln)))))) |
|
|
|
|
|
|
|
;;; Sort using fn to extract a value for less-than? to compare for each element in ln. |
|
|
|
(: sort-via (('a 'a -> boolean) ('b -> 'a) (list-of 'b) -> (list-of 'b))) |
|
|
|
(define (sort-via less-than? fn ln) |
|
|
|
(sort (lambda (a b) |
|
|
|
(less-than? (fn a) (fn b))) ln)) |
|
|
|
|
|
|
|
(: display-newline (string -> undefined)) |
|
|
|
(define (display-newline str) |
|
|
|
(display str) |
|
|
|
(newline)) |
|
|
|
|
|
|
|
(: ->string ((or string symbol number char) -> string)) |
|
|
|
(define (->string a) |
|
|
|
(cond ((string? a) a) |
|
|
|
((symbol? a) (symbol->string a)) |
|
|
@@ -68,6 +81,7 @@ |
|
|
|
;;; look up every symbol from left to right in the association list and replace it with the value found |
|
|
|
;;; then concatenate the resulting list of strings. |
|
|
|
;;; Inspired by Python 3's dictionary formatting string syntax. |
|
|
|
(: format-assoc ((list-of (or symbol string)) association-list --> string)) |
|
|
|
(define (format-assoc statement ln) |
|
|
|
(apply string-append |
|
|
|
(map (curry2 upon symbol? (compose ->string (curry (flip value) ln))) statement))) |
|
|
@@ -80,6 +94,7 @@ |
|
|
|
|
|
|
|
;;; The API key is an alphanumeric string of length 32 |
|
|
|
;;; The Linköping municipal open data API key generator portal is located at http://opendata.linkoping.se |
|
|
|
(: parking-key string) |
|
|
|
(define parking-key |
|
|
|
(string-delete char-set:whitespace (with-input-from-file "key-parking" read-line))) |
|
|
|
|
|
|
|