<div>Not bounded poly but still allows the type checker to catch ill typed attempts to make an undesirable node.</div><div><br></div>Define the node structure and constructor in a library.  Then use appropriate concrete constructor function(s) as needed. <div>
<br></div><div>To make SN nodes etc.</div><div><div>#lang typed/racket</div><div><br></div><div>(struct: () Node ({left : } {right : }))</div><div><br></div><div>(: create-node (All () (  -&gt; (Node ))))</div><div>
(define (create-node x y)</div><div>  (Node x y))</div><div><br></div><div>(define-type SN (U String Number))</div><div>(define-predicate sn? SN)</div><div><br></div><div>(define create-sn-nodes (inst create-node SN))</div>
<div>(define create-str-nodes (inst create-node String))</div><div><br></div><div>(create-sn-nodes &quot;ray&quot; 42.4) ;; ok</div><div>(create-sn-nodes &#39;x 4) ;; nope</div><div><br></div><div>(create-str-nodes &quot;x&quot; &quot;y&quot;) ;; yep</div>
<div>(create-str-nodes 2 &quot;z&quot;) ;; nada</div><div><br></div></div>