2015-10-20 126 views
0

在Elm中有什麼方法可以創建一個依賴於過去的函數,每次調用它時都會返回一個遞增的Int值? Signal.foldp幾乎在那裏,但我找不到要使用的信號!每次調用函數時都會增加一個Int?

這可能是,我想要做的是荒謬的,但基本的場景是我正在做一個數據網格。我(顯然,很難弄清楚如何做到這一點)需要每個單元在榆樹中都有一個唯一的ID,但並非所有的單元都可以保存到存儲中。所以我希望所有「空」單元自動獲得不同的負號。

回答

0

我最終的解決方案是完全放棄這個想法。單元格現在由其行和列標識,由視圖函數中嵌套的indexedMap調用生成。我決定將行和列作爲參數傳遞給單元格視圖函數,而不是將它們存儲在單元模型中,因爲只有父網格確實關心單元格的行和列。

我實際上不得不創建一個2D Array庫作爲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中真正做到這一點:祕密可變性被明確禁止。你需要在本土做一些事情。

如果您正在生成數據網格,每個單元格是否有行/列索引?你可以使用它們來生成標識符嗎?

你正在試圖做的可能會幫助如果建議沒有幫助:-)

+0

這實際上是我最終解決它的方法,以後會遇到很多麻煩。單元格視圖函數需要一個行和列參數,並且單元格數據被實現爲Array(Array Cell),我不得不編寫一個完整的二維數組庫來處理這個不痛苦的事情。 – wmakley

0

@grumpyjames'的想法是好的什麼更詳細一點。這裏有兩個:

  1. 如果你想要一個應用程序範圍內順序計數器,你可以有一個「最高(或最低)ID到目前爲止」變量模型,並使用它作爲一個函數的參數生成下一個ID;

  2. 如果每個ID只需要是唯一的,但不要求它們是順序的,則可以使用隨機數生成器併爲每個單元格指定一個UUID。那麼你不需要擔心狀態(儘管取決於榆樹如何生成隨機數,你可能需要堅持種子)。

伊萬

1

副作用必須在榆樹明確。

如果你想要一個函數產生效果,該函數需要返回一個Task(或者Effect),並且這個任務需要被髮送到一個端口執行。

Elm架構教程示例6到8提供瞭如何讓函數返回效果的示例(效果對於任務來說只是一個很好的界面)。這就是說,如果你的網格從一開始就是固定的,你可能根本不需要foldp。您可能能夠通過列表中的簡單摺疊來獲得。

下面是一個小例子來說明這一點。

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

謝謝,這很有趣。我還沒有學會如何使用任務和效果。 – 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

相關問題