I just stumble across ADT in python, and it translate into this in hy. Which is kinda ugly.
Here I present a macro, so it's looks a bit better:
macro implementation
(defmacro defadt [name #* constructors]
(let [alts []]
`(do
(import
__future__ [annotations]
dataclasses [dataclass])
~@(lfor alt constructors
(if (= (type alt) hy.models.List)
(let [[name #* fields] alt
fids (list (map
(fn [id] (hy.models.Symbol f"arg{(+ id 1)}"))
(range (len fields))))]
(alts.append name)
`(defclass [dataclass] ~name []
~@(lfor [f-id f-type] (list (zip fids fields))
`(annotate ~f-id ~f-type))
(defn __str__ [self]
(+ ~f"({name}"
~@(list
(map (fn [fid] `(+ " " (str (getattr self ~(str fid)))))
fids))
")"))))
(do
(alts.append alt)
`(defclass [dataclass] ~alt []
(defn __str__ [_]
~f"({alt})")))))
(setv ~name (| ~@alts)))))
(defadt Shape
[Point float float]
[Circle float float float]
[Rectangle float float float])
(Circle 3 4 5)
(defadt Tree
Dead
[Leaf int]
[Branch Tree Tree])
(Branch
(Branch (Leaf 1) (Leaf 2))
(Branch (Dead) (Branch (Dead) (Dead))))
But noted that not all properties is supported, because in my perspective we should keep adt simple.
I just stumble across ADT in python, and it translate into this in hy. Which is kinda ugly.
Here I present a macro, so it's looks a bit better:
macro implementation
But noted that not all properties is supported, because in my perspective we should keep adt simple.