How do I make an array of type aliased records and access those records using an index and known fields?

Made an alias:

type alias Node = {
    node_id:Int
    ,parent_id: Int
    ,child_ids: Array Int
    ,text: String
}

I made a model:

type alias Model = Array Node

init : Model

This gave me an error:

init  = [
    {
        node_id =0
        ,parent_id=0
        ,child_ids=[]
        ,text="This is the first node"
}
]

The compiler said that what I made was of type list.
How do I make it of type Array.

I saw that you can turn a list into an array using FromList. But I was wondering if there is a better way to do it.
Here is the compiler warning as a picture:

In Elm, the syntax with brackets is a list.

If you want an array, you need to use Array.fromList.

Consider using a list instead of Array, that is what I do most of the time.

Small remark: if you want the ability to use lookups via an index then an array is better than a list and if those indexes are not continuos you might even consider a Dict

perty already answered the question I think.

I hope you don’t mind but I think you are trying to implement some kind of tree here and maybe the representation you choose is not optimal (hard to tell since we know noting about what your are going to do with this).

Elm has union-types and often a good representation for trees is something like this:

type Node
   = Node { text : String, children : List Node }

(this would not include an empty-tree but I think it’s better to have an Maybe Node for this as representations involving Leaf or Empty or something kind of clashes with List being able to be empty as well)

1 Like

I had no idea you could do recursive type aliasing.(I don’t know if that’s a noobie thing) That is so cool. I dismissed the idea because when i program in other languages, their compiler would give me an error , so thank you for telling me this.

And about my project I am just trying to make a checklist program where I display the nodes as their own bullet point in the checklist and those items in the checklist can have sub-items.

Glad I could help.

Just to clarify: This here is no alias - it’s a union type with just one data-constructor :wink:

Is there no need for an alias?

An alias is more or less just another name for an type (in Elm you get a bit more - for example you’ll get an function to construct records but in principle it’s ok to think about it this way)

note that I added the Node before the record:

type Node
   = Node { text : String, children : List Node }

instead of

type alias Node
   = { text : String, children : List Node }

as you already noticed the second one would not work as you cannot define a recursive alias but you can of course define a recursive type and this is what the first one does.

1 Like

Just one more question. I define the Model using your help here and I have this.

type alias Model = Node

init : Model
init = Node { text="Toplevel", children = []  }

how would I access the text field because I used:

text model.text

In my view function

if you like you can write a helper function:

getText : Node -> String
getText (Node n) = n.text

and use it text (getText model) or instead you’d need to use pattern-matching/deconstruction - for example

...
let
  (Node node) = model
in
  text node.text

Small clarification, this isn’t a union type but a sum type. TypeScript has union types, e.g. type MyUnion = string | number;, while Elm has sum types, e.g. type MySum = MyString String | MyInt Int. The TS union type is either of type string or number while the Elm sum type is of type MySum and requires pattern matching (case .. of) to extract the String or Int.

1 Like

There is probably a right definition somewhere out there and I’m constantly struggling to use the right terms for the right communities.

For example F# calls them “Discriminated Unions”, Haskell usually “algebraic data type” (Sum is not really right here as in my example there is no sum and in the general case you can have a “product” build in with each data-constructor as you can have multiple componentents).

I actually like TypeScript here as it seems right there but I hope you can see where I’m coming from.

Ok I think I understand. I need to make a get text function for the node type. Thanks

In my current project, I use a lot of tree structures, and writing my own classes ended up with me over complicating a lot (which, granted, I do a lot anyway)…

These solutions are great to get a hang of the language but if you want to implement something without breaking your brain I’d wager elm-rosetree elm-rosetree 1.5.0.

Also one thing I would highly, highly recommend is learn from Elm code on Github, starting with elm-realworld. Elm is a simple language but making web apps is not. Most of the complexity comes from your business logic, and the great thing about Elm is how easy it is to study other people’s code. It has saved me days!

In terms of a custom tree structure used in code, I remember studying passiomatic/elm-designer. Maybe you can find some inspiration there!

1 Like