2

成功后,我在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是在 Elm 中实现的一种常见做法,所以我应该挑战clicks -> model依赖。

这是一些上下文:

我正在使用画布构建一个滑动益智游戏:

在此处输入图像描述

当用户单击可以移动的图块时,它应该会移动。否则,点击应该被忽略。

clicks将产生以下动作:Left, Right, Up,Down

例如,如果用户点击图块 12、11、8、15(按此顺序),clicks则应为:Down -> Right -> Up

问题是,为了计算点击了哪个图块,我需要知道板的尺寸(例如上图中的 4 行和 4 列)。但是,板尺寸存储在model(想象允许用户更改板尺寸的用户界面)中。

如何摆脱这种循环依赖?

4

1 回答 1

3

在这种情况下,我认为您应该在所谓的输入中更底层,并接受点击位置作为输入。然后你可以update在另外两个中组成一个函数Signal.foldp

  1. 第一个将点击和模型变成一个Maybe Direction(假设Left, Right, Up,Down是类型的构造函数Direction
  2. 第二个函数接受一个Direction值和模型来计算新模型。您可以使用Maybe.mapandMaybe.withDefault来处理Maybe第一个函数的部分结果。

即使您Direction立即生产和消费,将这两个部分分开也会使您的系统更具自我记录性,并显示原始输入和受限制的“实际”输入之间的概念划分。

PS Elm 语言有一些可以想象的扩展,可以让您更轻松地在信号域中编写这种输入预处理。但是这样的扩展将使语言的信号部分变得如此强大,以至于不清楚它是否会使构建程序的“正确方法”更难被发现。

于 2015-11-04T12:47:06.577 回答