<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>