From 2aa094c82af7132bc45667d62b709c83d09ccf4c Mon Sep 17 00:00:00 2001 From: Lassi Kortela Date: Tue, 17 Aug 2021 14:31:56 +0300 Subject: [PATCH] Add aplist library --- aplist.scm | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ aplist.sld | 11 +++++++++++ 2 files changed, 69 insertions(+) create mode 100644 aplist.scm create mode 100644 aplist.sld diff --git a/aplist.scm b/aplist.scm new file mode 100644 index 0000000..bd120a6 --- /dev/null +++ b/aplist.scm @@ -0,0 +1,58 @@ +;; Copyright 2021 Lassi Kortela +;; SPDX-License-Identifier: MIT + +;;; -> + +(define (alist->plist alist) + (let loop ((tail alist) (plist '())) + (if (null? tail) (reverse plist) + (let ((entry (car tail))) + (if (pair? entry) + (loop (cdr tail) + (cons (cdr entry) (cons (car entry) plist))) + (error "Invalid alist" alist)))))) + +(define (plist->alist plist) + (let loop ((tail plist) (alist '())) + (if (null? tail) (reverse alist) + (if (and (pair? tail) (pair? (cdr tail))) + (loop (cddr tail) + (cons (cons (car tail) (cadr tail)) alist)) + (error "Invalid plist" plist))))) + +;;; fold + +(define (alist-fold merge state alist) + (let loop ((tail alist) (state state)) + (if (null? tail) state + (let ((entry (car tail))) + (if (pair? entry) + (loop (cdr tail) (merge (car entry) (cdr entry) state)) + (error "Invalid alist" alist)))))) + +(define (plist-fold merge state plist) + (let loop ((tail plist) (state state)) + (if (null? tail) state + (if (and (pair? tail) (pair? (cdr tail))) + (loop (cddr tail) (merge (car tail) (cadr tail) state)) + (error "Invalid plist" plist))))) + +;;; for-each + +(define (alist-for-each fn alist) + (alist-fold (lambda (key val _) (fn key val) #f) + '() alist)) + +(define (plist-for-each fn plist) + (plist-fold (lambda (key val _) (fn key val) #f) + '() plist)) + +;;; map + +(define (alist-map fn alist) + (reverse (alist-fold (lambda (key val acc) (cons (fn key val) acc)) + '() alist))) + +(define (plist-map fn plist) + (reverse (plist-fold (lambda (key val acc) (cons (fn key val) acc)) + '() plist))) diff --git a/aplist.sld b/aplist.sld new file mode 100644 index 0000000..9685a06 --- /dev/null +++ b/aplist.sld @@ -0,0 +1,11 @@ +(define-library (alist) + (export alist->plist + plist->alist + alist-fold + plist-fold + alist-for-each + plist-for-each + alist-map + plist-map) + (import (scheme base)) + (include "aplist.scm"))