Parametric polymorphism: Difference between revisions

Content added Content deleted
(Added C3 example)
Line 776: Line 776:


=={{header|Julia}}==
=={{header|Julia}}==
{{works with|Julia|1.3.1}}
{{works with|Julia|1.6}}


<lang julia>mutable struct Tree{T}
<lang julia>module BinaryTrees

val::T
mutable struct BinaryTree{V}
lchild::Union{Tree{T}, Nothing}
v::V
rchild::Union{Tree{T}, Nothing}
l::Union{BinaryTree{V}, Nothing}
r::Union{BinaryTree{V}, Nothing}
end
end


Tree(v::T) where T = Tree(v, nothing, nothing) # Single arg constructor
BinaryTree(v) = BinaryTree(v, nothing, nothing)

map(f, bt::BinaryTree) = BinaryTree(f(bt.v), map(f, bt.l), map(f, bt.r))
map(f, bt::Nothing) = nothing

let inttree = BinaryTree(
0,
BinaryTree(
1,
BinaryTree(3),
BinaryTree(5),
),
BinaryTree(
2,
BinaryTree(4),
nothing,
),
)
map(x -> 2x^2, inttree)
end


let strtree = BinaryTree(
"""
"hello",
Apply `f` (element-wise and in-place) to the values in tree `bt`.
BinaryTree(
Also prints the tree like an s-expression *for demonstrative purposes only*,
"world!",
new types should overload the `show()` function for pretty-printing.
BinaryTree("Julia"),
"""
nothing,
function map!(f::Function, bt::Tree{T}) where T
bt.val= f(bt.val)
),
BinaryTree(
print(" (" * string(bt.val)) # Demonstration only
"foo",
bt.lchild !== nothing && map!(f, bt.lchild)
BinaryTree("bar"),
bt.rchild !== nothing && map!(f, bt.rchild)
BinaryTree("baz"),
print(")") # Demonstration only
),
)
map(uppercase, strtree)
end
end


function test_treemap()
inttree = Tree(0,
Tree(1,
Tree(3),
Tree(5)),
Tree(2,
Tree(4),
nothing))
map!(x -> 2x^2, inttree) # Pass an anonymous function
# (0 (2 (18) (50)) (8 (32)))
println()
strtree = Tree("hello",
Tree("world!",
Tree("Julia"),
nothing),
Tree("foo",
Tree("bar"),
Tree("baz")))
map!(uppercase, strtree)
# (HELLO (WORLD! (JULIA)) (FOO (BAR) (BAZ)))
end</lang>
end</lang>