每次调用函数时增加一个 Int?

Increment an Int every time function is called?

在 Elm 中,有什么方法可以创建一个依赖于过去的函数,每次调用它时 returns 都是一个递增的 Int 吗? Signal.foldp 快到了,但我找不到可以使用的信号!

我尝试做的事情可能是荒谬的,但基本情况是我正在制作数据网格。我(显然,很难弄清楚如何做到这一点)需要每个单元格在 elm 中都有一个唯一的 ID,但并不是所有的单元格都可以持久保存到存储中。所以我希望所有 "empty" 个单元格自动获得不同的否定 ID。

这很棘手:您希望函数秘密地保持某种状态,并在每次调用该函数时改变它。你不能在 Elm 中真正做到这一点:秘密可变性是明确不允许的。你需要在本土做点什么。

如果您要生成数据网格,是否每个单元格都有一个 row/column 索引?你能用它们来生成标识符吗?

如果该建议没有帮助,关于您尝试做的事情的更多细节可能会有所帮助:-)

@grumpyjames 的想法不错。这里还有两个:

  1. 如果你想要一个应用程序范围的序列计数器,你可以在你的模型中有一个 'highest (or lowest) ID so far' 变量,并将它用作函数中的参数来生成下一个 ID;

  2. 如果每个 ID 只需要是唯一的,但不要求它们是连续的,则可以使用随机数生成器并为每个单元格指定一个 UUID。那么你就不需要担心状态(尽管,根据 Elm 如何生成随机数,你可能需要保留种子)。

伊万

Elm 中的副作用必须明确。

如果您想让一个函数产生效果,该函数需要 return 一个任务(或效果),并且该任务需要发送到端口执行。

Elm 体系结构教程示例 6 到 8 提供了如何具有 return 效果的函数的示例(效果只是任务的一个很好的接口)。

也就是说,如果您的网格从一开始就是固定的,您可能根本不需要 foldp。您可以使用 List 中的简单 foldl 来解决问题。

这里有一个小例子来说明这一点。

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 

我最终的解决方案是完全放弃这个想法。单元格现在由它们的行和列标识,由视图函数中的嵌套 indexedMap 调用生成。我决定将行和列作为参数传递给 Cell 视图函数,而不是将它们存储在 Cell 模型中,因为只有父 Grid 真正关心单元格是什么行和列。

我实际上必须创建一个 2D 数组库作为数组(数组 a)的包装器,因为有必要能够获取和设置单个单元格而不映射整个网格。

这可能不再实际了,但如果您为数据网格单元格创建一个模块,您可以向模型添加一个计数器并在每次调用更新时递增它:

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
    }

现在在 Elm 0.17 中信号消失了,所以我想现在容易多了