Как распространить сигнал о кликах для обновления модели в Elm?

Я пишу игру в Elm, и в этой игре есть кнопка, которая при нажатии должна вернуть игровое поле в исходное состояние. Я не понимаю, однако, как сигнал нажатия кнопки должен распространяться на функцию обновления модели платы. В приведенном ниже коде я только что передал значение единицы stepBoard но я ничего не могу с этим поделать, так как я могу решить это?

--MODEL
type Board = [(Int,Int)]
type Game = {name: String, board: Board}
defaultGame = {name = "Test", board = [(3,3)]}

--UPDATE
stepBoard click (colsInit, rowsInit) (rows, cols) g = 
          {g | board <- if ? then --some initial value (colsInit, rowsInit)
                        else      --some updated value using (rows, cols)} 
stepGame: Input -> Game -> Game                                      
stepGame {click, name, rowsColsInit, rowsCols} g = stepBoard click (0,0) (0,0) g
game = foldp stepGame defaultGame input

--INPUT
type Input = {click:(), name: String, rowsColsInit: (Int,Int), rowsCols: (Int,Int)}
input = Input <~ clicks ~ nameSignal ~ rowsColsInitSignal ~ rowsColsSignal

--VIEW
(btn, clicks) = Input.button "Click"

1 ответ

Решение

Объединяя foldp и информация о клике может быть неинтуитивной.

Обычное используемое решение - это ADT для кодирования различных возможных событий:

data Input = Init (Int, Int)
           | Update { name         : String
                    , rowsCols     : ( Int, Int )
                    }
input = merge (Init <~ (sampleOn clicks rowsColsInitSignal))
              (OtherInput <~ nameSignal ~ rowsColsSignal)

merge объединяет два сигнала и always создает постоянную функцию.

Теперь вы можете просто сопоставлять данные в своей функции обновления:

stepBoard input g = 
  let newBoard = 
        case input of
          Init (initRows, initCols) -> -- do your initialisation here
          Update {name, rowsCols}   -> -- do your update here
  in { g | board <- newBoard }
Другие вопросы по тегам