Jump to content

Algebraic data types: Difference between revisions

Added Go
(Removed {{omit from|Go}} template as ADTs can be simulated using interfaces.)
(Added Go)
Line 561:
> rbtree:find(4,T8).
{found,{4,-3}}
</pre>
 
=={{header|Go}}==
{{trans|Kotlin}}
<br>
Go doesn't have algebraic data types as such though they can simulated (to a limited extent) by interfaces.
 
However, pattern matching on interfaces (via the type switch statement and type assertions) is limited to matching the implementing type and so the balance() method is not very pleasant.
<lang go>package main
 
import "fmt"
 
type Color string
 
const (
R Color = "R"
B = "B"
)
 
type Tree interface {
ins(x int) Tree
}
 
type E struct{}
 
func (_ E) ins(x int) Tree {
return T{R, E{}, x, E{}}
}
 
func (_ E) String() string {
return "E"
}
 
type T struct {
cl Color
le Tree
aa int
ri Tree
}
 
func (t T) balance() Tree {
if t.cl != B {
return t
}
le, leIsT := t.le.(T)
ri, riIsT := t.ri.(T)
var lele, leri, rile, riri T
var leleIsT, leriIsT, rileIsT, ririIsT bool
if leIsT {
lele, leleIsT = le.le.(T)
}
if leIsT {
leri, leriIsT = le.ri.(T)
}
if riIsT {
rile, rileIsT = ri.le.(T)
}
if riIsT {
riri, ririIsT = ri.ri.(T)
}
switch {
case leIsT && leleIsT && le.cl == R && lele.cl == R:
_, t2, z, d := t.destruct()
_, t3, y, c := t2.(T).destruct()
_, a, x, b := t3.(T).destruct()
return T{R, T{B, a, x, b}, y, T{B, c, z, d}}
case leIsT && leriIsT && le.cl == R && leri.cl == R:
_, t2, z, d := t.destruct()
_, a, x, t3 := t2.(T).destruct()
_, b, y, c := t3.(T).destruct()
return T{R, T{B, a, x, b}, y, T{B, c, z, d}}
case riIsT && rileIsT && ri.cl == R && rile.cl == R:
_, a, x, t2 := t.destruct()
_, t3, z, d := t2.(T).destruct()
_, b, y, c := t3.(T).destruct()
return T{R, T{B, a, x, b}, y, T{B, c, z, d}}
case riIsT && ririIsT && ri.cl == R && riri.cl == R:
_, a, x, t2 := t.destruct()
_, b, y, t3 := t2.(T).destruct()
_, c, z, d := t3.(T).destruct()
return T{R, T{B, a, x, b}, y, T{B, c, z, d}}
default:
return t
}
}
 
func (t T) ins(x int) Tree {
switch {
case x < t.aa:
return T{t.cl, t.le.ins(x), t.aa, t.ri}.balance()
case x > t.aa:
return T{t.cl, t.le, t.aa, t.ri.ins(x)}.balance()
default:
return t
}
}
 
func (t T) destruct() (Color, Tree, int, Tree) {
return t.cl, t.le, t.aa, t.ri
}
 
func (t T) String() string {
return fmt.Sprintf("T(%s, %v, %d, %v)", t.cl, t.le, t.aa, t.ri)
}
 
func insert(tr Tree, x int) Tree {
t := tr.ins(x)
switch t.(type) {
case T:
tt := t.(T)
_, a, y, b := tt.destruct()
return T{B, a, y, b}
case E:
return E{}
default:
return nil
}
}
 
func main() {
var tr Tree = E{}
for i := 1; i <= 16; i++ {
tr = insert(tr, i)
}
fmt.Println(tr)
}</lang>
 
{{out}}
<pre>
T(B, T(B, T(B, T(B, E, 1, E), 2, T(B, E, 3, E)), 4, T(B, T(B, E, 5, E), 6, T(B, E, 7, E))), 8, T(B, T(B, T(B, E, 9, E), 10, T(B, E, 11, E)), 12, T(B, T(B, E, 13, E), 14, T(B, E, 15, T(R, E, 16, E)))))
</pre>
 
9,482

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.