blob: c9ce4a48fc71707f2677e526728f77cf4545a055 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
;;; iso.el --- Isomorphisms in Elisp -*- lexical-binding: t -*-
;; Author: William Carroll <wpcarro@gmail.com>
;;; Commentary:
;; Providing basic isomorphisms to improve code quality.
;;; Code:
(require 'dotted)
(require 'tuple)
(require 'symbol)
(require 'string)
(require 'list)
(require 'alist)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Library
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(cl-defstruct iso to from x)
(defconst iso/whitelist
'((dotted . tuple)
(symbol . string))
"Alist representing supported isomorphisms.")
(defconst iso/vertices
(list/concat (alist/keys iso/whitelist)
(alist/values iso/whitelist))
"List of all of the vertices in the iso graph.")
(defun iso/classify (x)
"Return type of X."
(cond
((string/instance? x) 'string)
((symbol/instance? x) 'symbol)
((dotted/instance? x) 'dotted)
((tuple/instance? x) 'tuple)))
(cl-defun iso/exists? (to from)
"Return t if an isomorphism of TO to FROM exists."
;; TODO: All of this can be improved modelling this with a graph.
(cond
;; to -> from
((list/contains? to (alist/keys iso/whitelist))
(list/contains? from (alist/values iso/whitelist)))
;; from -> to
((list/contains? from (alist/keys iso/whitelist))
(list/contains? to (alist/values iso/whitelist)))
;; doesn't exist
(t nil)))
(progn
(prelude/assert
(iso/exists? 'symbol 'string))
(prelude/assert
(iso/exists? 'dotted 'tuple))
(prelude/refute
(iso/exists? 'dotted 'symbol))
(prelude/refute
(iso/exists? 'symbol 'list)))
;; TODO: Model this as a graph.
(defconst iso/morphisms
'((string .
'(symbol #')
))
(list (:from 'string :to 'symbol :fn #'intern)
(:from 'symbol :to 'string :fn #'symbol-name)
)
"")
(defun iso/to (f x)
"Apply F to X's to."
(->> x
iso-to))
(->> (iso/new "william" :to 'symbol)
(iso/as-to #'symbol-name)
)
(cl-defun iso/new (x &key to)
"Create a new isomorphism of X mapping to TO."
(let ((from (iso/classify x)))
(prelude/assert (iso/exists? to from))
(make-iso :from from
:to to
:x x)))
(macros/comment
(iso/new "william" :to 'symbol)
(iso/new '(one . two) :to 'tuple))
(provide 'iso)
;;; iso.el ends here
|