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:
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
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)
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.
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.
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.
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.
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!