While elm-make
succeeds, I get the following error in the browser:
Cannot read property 'kids' of undefined
I assume it's because I have a circular dependency of signals:
model -> clicks -> model
Here is the relevant code:
model : Signal Model
model =
Signal.foldp update initialModel clicks
clicks : Signal Action
clicks =
let
clickPosition = Mouse.position
|> Signal.sampleOn Mouse.clicks
tuplesSignal = Signal.map3 (,,) clickPosition Window.dimensions model
in
...
It feels like model
is implemented as a common practice in Elm, so I should challenge the clicks -> model
dependency.
Here is some context:
I'm building a sliding puzzle game using canvas:
When user clicks a tile that can move, it should move. Otherwise, the click should be ignored.
clicks
will produce the following actions: Left
, Right
, Up
, Down
For example, if user clicks on tiles 12, 11, 8, 15 (in this order), clicks
should be: Down -> Right -> Up
The problem is, that in order to calculate which tile was clicked, I need to know the board dimensions (e.g. 4 rows and 4 columns in the picture above). But, board dimensions are stored in the model
(imagine user interface that allows users to change board dimensions).
How do I get out of this circular dependency?
In this case I think you should go more low-level in what you call an input, and accept click positions as inputs. Then you can compose an update
function in your Signal.foldp
out of two others:
Maybe Direction
(assuming the Left
, Right
, Up
, Down
are constructors of type Direction
)Direction
value and the model to calculate the new model. You can use Maybe.map
and Maybe.withDefault
to handle the Maybe
part of the result of the first function. Separating these two parts, even though you produce and consume Direction
immediately, makes your system more self-documenting and shows the conceptual split between the raw input and the restricted "actual" inputs.
P.S. There are conceivable extensions to the Elm language that would allow you to more easily write this input preprocessing in signal-land. But such extensions would make the signal part of the language so much more powerful that it's unclear if it would make "the right way" to structure programs harder to discover.