Ah, you need to tag your renderComponent
function with the same type:
renderComponent : Component ComponentType -> Html Msg
You should then be good to go. You’ll need to do this with all your functions that take Component
as an argument.
Ah, you need to tag your renderComponent
function with the same type:
renderComponent : Component ComponentType -> Html Msg
You should then be good to go. You’ll need to do this with all your functions that take Component
as an argument.
That works! I was losing my mind. Thank you again!
So if I understand correctly I need to use World data in my Ecs.elm file, and World ComponentType in my app that usees the library?
To a point yes, it depends on what you are trying to achieve.
You are right about Ecs.elm
, but in your app that uses the library, it depends on your use case.
If you need to access the data
field, then you will need to tag your functions with ComponentType
(as you have just done) rather than the type variable data
so that the compiler knows what type it is dealing with, if however you are accessing one of the other fields, then you can use the the type variable data
in your functions:
-- This will work fine in your app
isEnabled : Component data -> Bool
isEnabled component =
component.isEnabled
-- Or this
isEnabled : Component data -> Bool
isEnabled =
.isEnabled
-- Or this where the type variable is not accessed, so it can just 'flow through'
setEnabled : Bool -> Component data -> Component data
setEnabled val component =
{ component | isEnabled = val }
Type variables are really cool, they enable code re-use while also restricting what the function can do, and so protecting the purity of the function.
Check out the docs for List
for example, and you’ll see type variables in use. If you look at the map
function you will see it’s type signature is:
map : (a -> b) -> List a -> List b
I’ll assume know how to use List.map
, but the use of type variables means that it will work on any type of list, it also helps to guarantee that it can only do what it’s type signature says it can do. So imagine if type variables didn’t exist, and instead we had:
mapString : (String -> String) -> List String -> List String
Now, without checking the underlying code, there is no guarantee that the creator of that function didn’t decide that it would also be a good thing to reverse the Strings as well as mapping the function to each String
in the list. There are no guarantees that the Strings
are not also being transformed in some way.
But as you have seen with your data
type variable, the compiler will not allow a type variable to be transformed by the internals of the function - and so the type signature can be trusted. Using type variables narrows what the function can do to only what it knows about - in the case of List.map
that is simply applying the provided function to each element in the list and returning the transformed list.
Here’s a link to the Elm docs: Reading Types · An Introduction to Elm scroll down to find the section about type variables.
HTH a bit.
This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.