2015-10-20 3 views
0

В Elm есть ли способ создать зависимую от прошлого функцию, которая возвращает инкрементированный Int каждый раз, когда он вызывается? Signal.foldp почти есть, но я не могу найти сигнал для использования!Приращение функции int каждый раз?

Возможно, что то, что я пытаюсь сделать, бессмысленно, но основным сценарием является создание datagrid. Мне (по-видимому, очень сложно понять, как это сделать) нужно, чтобы каждая ячейка имела уникальный идентификатор в вязах, но не все ячейки могут быть сохранены в хранилище. Поэтому я хотел бы, чтобы все «пустые» ячейки автоматически получали разные отрицательные идентификаторы.

ответ

0

Моим возможным решением было отказаться от этой идеи полностью. Ячейки теперь идентифицируются по их строкам и столбцам, генерируемым вложенными запросами indexedMap в функции просмотра. Я решил передать строку и столбец функции Cell view в качестве аргументов, а не хранить их в модели Cell, потому что только родительская Grid действительно заботится о том, какая строка и столбец ячейки.

Мне действительно нужно было создать библиотеку 2D-массива в качестве оболочки для Array (Array a), поскольку необходимо было иметь возможность получать и устанавливать отдельные ячейки без отображения по всей сетке.

+0

Есть ли что-нибудь, что вам не нравится в моей библиотеке [matrix] (http://package.elm-lang.org/packages/sindikat/elm-matrix/1.2.0/Matrix)? Не стесняйтесь предлагать какие-либо недостающие функции на GitHub [вопросы] (https://github.com/sindikat/elm-matrix). –

1

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

Если вы генерируете datagrid, каждая ячейка имеет индекс строки/столбца? Не могли бы вы использовать их для генерации идентификатора?

Чуть более подробно о том, что вы пытаетесь сделать, может помочь, если это предложение не поможет идея :-)

+0

Это на самом деле то, как я в конце концов решил это, многие головные боли позже. Функция представления ячейки принимает аргумент строки и столбца, а данные ячейки реализованы как Array (Array Cell), и мне пришлось написать целую библиотеку 2D-массива, чтобы сделать работу с этим не мучительной. – wmakley

0

@grumpyjames' хорошо. Вот еще два:

  1. Если вы хотите счетчик последовательности приложения шириной, вы могли бы иметь «высокий (или низкий) ID до сих пор» переменной в модели, и использовать его в качестве аргумента в функции для генерации следующего идентификатора;

  2. Если каждый идентификатор должен быть уникальным, но вы не требуете, чтобы он был последовательным, вы можете использовать генератор случайных чисел и дать каждой ячейке UUID. Тогда вам не нужно беспокоиться о состоянии (хотя, в зависимости от того, как Elm производит случайное число, вам, возможно, придется держаться за семя).

Иван

1

побочные эффекты должны быть явными в Эльм.

Если вы хотите, чтобы функция имела эффект, эта функция должна вернуть задачу (или эффект), и эта задача должна быть отправлена ​​в порт для выполнения.

В примере с 6 по 8 учебника по архитектуре Elm приведены примеры того, как выполнять функции, возвращающие эффекты (эффекты - это просто приятный интерфейс к задачам).

Это означает, что если ваша сетка фиксирована с самого начала, вам может не потребоваться сложение. Возможно, вы сможете пройти простым списком из списка.

Вот небольшой пример, чтобы показать это.

import Html exposing (..) 


type alias Data = List (Int, Int, Bool) 

type alias ID = Int 

type alias TaggedData = List (ID, (Int, Int, Bool)) 

data : Data 
data = [ (0,0, True), (0,1, False) 
     , (1,0, True), (1,1, False)] 



toTaggedData : Data -> TaggedData 
toTaggedData d = 
    let 
    f (x, y, v) (pos, neg, acc) = 
     if v 
     then ((pos+1), neg, (pos, (x, y, v))::acc) 
     else (pos, (neg-1), (neg, (x, y, v))::acc) 
    (max, min, list) = List.foldl f (1, -1, []) d 
    in 
    List.reverse list 

main = text <| toString <| toTaggedData data 
+0

Спасибо, это довольно интересно. Я еще не научился использовать Tasks and Effects. – wmakley

0

Это, вероятно, не актуально больше, но если вы создаете модуль для сетки данных ячеек можно добавить счетчик модели и увеличить его каждое обновление времени называется:

type alias Model = 
    { content : String 
    , counter : Int 
    } 

update : Msg -> Model -> Model 
update msg model = 
    case msg of 
    Change newContent -> 
    { model | 
    content = newContent 
    , counter = model.counter + 1 
    } 

В настоящее время в Эом 0.17 Сигналов ушли, поэтому я думаю, что теперь намного легче fwiw

Смежные вопросы