Не удается прочитать свойство 'kids' из undefined - или как нарушить циклическую зависимость сигналов в Elm?
В то время как elm-make
успешно, я получаю следующую ошибку в браузере:
Невозможно прочитать свойство "дети" из неопределенного
Я предполагаю, что это потому, что у меня круговая зависимость сигналов:
model -> clicks -> model
Вот соответствующий код:
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
...
Похоже на model
В Эльме это общепринятая практика, поэтому я должен clicks -> model
зависимость.
Вот некоторый контекст:
Я строю скользящую головоломку, используя холст:
Когда пользователь щелкает плитку, которая может двигаться, она должна двигаться. В противном случае щелчок следует игнорировать.
clicks
произведет следующие действия: Left
, Right
, Up
, Down
Например, если пользователь нажимает на плитки 12, 11, 8, 15 (в этом порядке), clicks
должно быть: Down -> Right -> Up
Проблема в том, что для того, чтобы вычислить, на какой плитке был нажат, мне нужно знать размеры доски (например, 4 строки и 4 столбца на рисунке выше). Но размеры платы хранятся в model
(представьте пользовательский интерфейс, который позволяет пользователям изменять размеры платы).
Как мне выйти из этой круговой зависимости?
1 ответ
В этом случае я думаю, что вы должны перейти на более низкий уровень в том, что вы называете входом, и принять позиции нажатия в качестве входных данных. Тогда вы можете составить update
функция в вашем Signal.foldp
из двух других:
- Первый превращает клики и модель в
Maybe Direction
(при условииLeft
,Right
,Up
,Down
являются конструкторами типаDirection
) - Вторая функция, которая принимает
Direction
стоимость и модель для расчета новой модели. Ты можешь использоватьMaybe.map
а такжеMaybe.withDefault
обращаться сMaybe
часть результата первой функции.
Разделение этих двух частей, даже если вы производите и потребляете Direction
немедленно, делает вашу систему более самодокументированной и показывает концептуальное разделение между необработанным вводом и ограниченным "фактическим" вводом.
PS Есть мыслимые расширения языка Elm, которые позволили бы вам легче написать эту предварительную обработку ввода в сигнальной земле. Но такие расширения сделают сигнальную часть языка настолько мощной, что неясно, сделает ли это "правильный путь" структурирования программ более трудным для обнаружения.