# MLStyle - are recursive ADTs possible

**URL:** https://discourse.julialang.org/t/mlstyle-are-recursive-adts-possible/127083
**Category:** New to Julia
**Created:** [March 18, 2025, 7:29am UTC](https://discourse.julialang.org/t/mlstyle-are-recursive-adts-possible/127083 "2025-03-18T07:29:59Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![jonoke](https://avatars.discourse-cdn.com/v4/letter/j/a8b319/32.png) [@jonoke](https://discourse.julialang.org/u/jonoke)
#### Post date: [March 18, 2025, 7:29am UTC](https://discourse.julialang.org/t/mlstyle-are-recursive-adts-possible/127083/1 "2025-03-18T07:29:59Z")

</div>

Hi,

I’m playing around with MLStyle but can’t seem to get a definition for a cons list to work.

If I try:

```julia
@data XX{T} begin
    Nil
    Cons(hd::T, tl::XX{T})
end

```

I get: ERROR: LoadError: Defining generic enum Nil \<: XX{T} is invalid, as Julia does not support generic value.

If I try:

```julia
@data XX{T} begin
    Nil()
    Cons(hd::T, tl::XX{T})
end

```

I get: MethodError: no method matching List.Nil()  
The type `List.Nil` exists, but no method is defined for this combination of argument types when trying to construct it.

---

<div class="post-metadata">

### Author: ![jonoke](https://avatars.discourse-cdn.com/v4/letter/j/a8b319/32.png) [@jonoke](https://discourse.julialang.org/u/jonoke)
#### Post date: [March 18, 2025, 8:02pm UTC](https://discourse.julialang.org/t/mlstyle-are-recursive-adts-possible/127083/2 "2025-03-18T20:02:23Z")

</div>

OK, I’m not sure why, but the solution is less, not more …

```julia
@data XX begin
    Nil
    Cons(hd, tl::XX)
end
function sum_list(lst)
    @match lst begin
        Nil => 0
        Cons(h, t) => h + sum_list(t)
    end
end
function printer(lst)
    @match lst begin
      Nil => println("[]")
      Cons(h, t) => begin
        print("$(h) . ")
        printer(t)
      end
    end
end
function make_test_1()
  return Cons(1, Cons(2, Cons(3, Nil)))
end
function make_test_2()
  return Cons("A", Cons("B", Cons("C", Nil)))
end
i = make_test_1()
s = make_test_2()
println("sum_list(i) = $(sum_list(i))")
#sum_list(i) = 6
printer(i)
#1 . 2 . 3 . []
printer(s)
#A . B . C . []

```

---

<div class="post-metadata">

### Author: ![jonoke](https://avatars.discourse-cdn.com/v4/letter/j/a8b319/32.png) [@jonoke](https://discourse.julialang.org/u/jonoke)
#### Post date: [March 18, 2025, 10:22pm UTC](https://discourse.julialang.org/t/mlstyle-are-recursive-adts-possible/127083/3 "2025-03-18T22:22:37Z")

</div>

except that allows …

```julia
function make_test_3()
  return Cons("A", Cons(1.2, Cons("C", Nil)))
end
printer(make_test_3())
#A . 1.2 . C . []

```

which is not what I want … I want an homogenous list.

Is this the best place to get help?

---

<div class="post-metadata">

### Author: ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)
#### Post date: [March 18, 2025, 10:37pm UTC](https://discourse.julialang.org/t/mlstyle-are-recursive-adts-possible/127083/4 "2025-03-18T22:37:58Z")

</div>

Moshi.jl might do what you want.

```julia
using Moshi.Data: @data

julia> @data XX{T} begin
           Nil
           Cons(T, XX{T})
       end

julia> using .XX: Nil, Cons

julia> Cons('a', Cons('b', Nil{Char}()))
Main.XX.var"typeof(XX)"{Char}(Main.XX.var"##Storage#Cons"{Char}('a', Main.XX.var"typeof(XX)"{Char}(Main.XX.var"##Storage#Cons"{Char}('b', Main.XX.var"typeof(XX)"{Char}(Main.XX.var"##Storage#Nil"{Char}())))))

```

Really ugly representation but I think it’s the right value.

And heterogeneous lists fail like you want:

```julia
julia> Cons('a', Cons(1.2, Nil{Char}()))
ERROR: MethodError: no method matching Cons(::Float64, ::Main.XX.var"typeof(XX)"{Char})
The type `Cons` exists, but no method is defined for this combination of argument types when trying to construct it.

```

---

<div class="post-metadata">

### Author: ![nandoconde](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nandoconde/32/19497_2.png) [@nandoconde](https://discourse.julialang.org/u/nandoconde)
#### Post date: [March 19, 2025, 12:08am UTC](https://discourse.julialang.org/t/mlstyle-are-recursive-adts-possible/127083/5 "2025-03-19T00:08:12Z")

</div>

Representation can be improved with:

```julia
import Moshi.Derive: @derive

@derive XX[Show]

```

---

<div class="post-metadata">

### Author: ![jonoke](https://avatars.discourse-cdn.com/v4/letter/j/a8b319/32.png) [@jonoke](https://discourse.julialang.org/u/jonoke)
#### Post date: [March 19, 2025, 12:29am UTC](https://discourse.julialang.org/t/mlstyle-are-recursive-adts-possible/127083/6 "2025-03-19T00:29:20Z")

</div>

> [@jar1](#):
>
> `using Moshi.Data: @data`

I can’t get Moshi to work … here is my package

```julia
module List

using Moshi.Data: @data
using Moshi.Match: @match

export sum_list, make_test_1, make_test_2, printer

@data XX{T} begin
    Nil
    Cons(T, XX{T})
end
function sum_list(lst)
    @match lst begin
        Nil => 0
        Cons(h, t) => h + sum_list(t)
    end
end
function printer(lst)
    @match lst begin
      Nil => println("[]")
      Cons(h, t) => begin
        print("$(h) . ")
        printer(t)
      end
    end
end
function make_test_1()
  return Cons(1, Cons(2, Cons(3, Nil)))
end
function make_test_2()
  return Cons("A", Cons("B", Cons("C", Nil)))
end
end # module List

```

my test program is just doing this

```julia
using Test
using List

@testset "Simple Cons" begin
  s = make_test_2()
  printer(s)
end

```

I get this error: ERROR: LoadError: UndefVarError: `Cons` not defined in `List`

---

<div class="post-metadata">

### Author: ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)
#### Post date: [March 19, 2025, 12:30am UTC](https://discourse.julialang.org/t/mlstyle-are-recursive-adts-possible/127083/7 "2025-03-19T00:30:37Z")

</div>

You have to do `using ..XX: Nil, Cons` or use `XX.Nil` and `XX.Cons`.

---

<div class="post-metadata">

### Author: ![jonoke](https://avatars.discourse-cdn.com/v4/letter/j/a8b319/32.png) [@jonoke](https://discourse.julialang.org/u/jonoke)
#### Post date: [March 19, 2025, 12:44am UTC](https://discourse.julialang.org/t/mlstyle-are-recursive-adts-possible/127083/8 "2025-03-19T00:44:02Z")

</div>

OK, that seems strange to need a “using” **inside** the module that defines those things …

I put the using directly after the @data:

```julia
@data XX{T} begin
    Nil
    Cons(T, XX{T})
end
using ..XX: Nil, Cons

```

and now I get  
MethodError: no method matching List.XX.Cons(::String, ::Type{List.XX.Nil{String}})  
The type `List.XX.Cons` exists, but no method is defined for this combination of argument types when trying to construct it.

Closest candidates are:  
List.XX.Cons(::T, ::List.XX.var"typeof(XX)"{T}) where T

I get a very similar error whether I have just Nil or Nil{String} in the example construction.

---

<div class="post-metadata">

### Author: ![nandoconde](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nandoconde/32/19497_2.png) [@nandoconde](https://discourse.julialang.org/u/nandoconde)
#### Post date: [March 19, 2025, 2:57pm UTC](https://discourse.julialang.org/t/mlstyle-are-recursive-adts-possible/127083/9 "2025-03-19T14:57:58Z")

</div>

> [@jonoke](#):
>
> ```julia
> function make_test_1()
> return Cons(1, Cons(2, Cons(3, Nil)))
> end
> function make_test_2()
> return Cons("A", Cons("B", Cons("C", Nil)))
> end
> 
> ```

You have to instantiate the `Nil` ADT’s:

```julia
function make_test_1()
  return Cons(1, Cons(2, Cons(3, Nil{Int}())))
end
function make_test_2()
  return Cons("A", Cons("B", Cons("C", Nil{String}())))
end

```

---

<div class="post-metadata">

### Author: ![nandoconde](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nandoconde/32/19497_2.png) [@nandoconde](https://discourse.julialang.org/u/nandoconde)
#### Post date: [March 19, 2025, 2:58pm UTC](https://discourse.julialang.org/t/mlstyle-are-recursive-adts-possible/127083/10 "2025-03-19T14:58:47Z")

</div>

> [@jonoke](#):
>
> ```julia
> s = make_test_2()
> printer(s)
> 
> ```

Of course, this errors too because the code generated for `@match` in recursive ADTs seems to be not good, but that’s something you can open an issue about.

---

<div class="post-metadata">

### Author: ![jonoke](https://avatars.discourse-cdn.com/v4/letter/j/a8b319/32.png) [@jonoke](https://discourse.julialang.org/u/jonoke)
#### Post date: [March 19, 2025, 9:05pm UTC](https://discourse.julialang.org/t/mlstyle-are-recursive-adts-possible/127083/11 "2025-03-19T21:05:32Z")

</div>

Thanks for the help people, but I think the lesson may be, I need to give up my functional fetishes when I’m using Julia. Embrace the array! 🙂
