還是回到一開始的老話,程式其實就是data structure和algorithm,我也是過了好久才懂這句話,如果不懂也沒關係。學Elm會讓你更懂(其實我覺得是學Haskell,之後再來寫Haskell好了)。不同的data structure 會有不同的方式,這裡也不是只有針對Elm,廣泛適用於Elixir, Erlang, Haskell等functional programming。 我們先來看list,你可以在elm-repl裡試試:
3 :: []
-- [3]
1 :: (2 :: (3 :: []))
-- [1,2,3] : List number
List.head ([1, 2, 3]) -- Just 1
List.tail ([1, 2, 3]) -- Just [2, 3]
這種在functional programming world的List叫 linked list。他加入元素是從 頭
開始加的,如果你要從尾巴加入新的元素,會變得很麻煩;或是你要指定某個index的元素出來時,也會很麻煩。
Array,就是這個時候好用。
import Array exposing (..)
testArray = Array.fromList [1, 2, 3]
Array.get 2 testArray -- Just 3
Array.get 1 testArray -- Just 2
Array.push 4 testArray --Array.fromList [1,2,3,4]
還有一個Key-Value pair可以在Elm裡使用的是 Dict
data :: Dict String Int
data = Dict.fromList
[ ("John", 58)
, ("Kethy", 27)
, ("Snow", 30)
, ("Mary", 10)
]
Dict.insert "Kevin" 42 data
Dict.get "Mary" data
Dict.values -- [58, 27, 30, 10, 42]
當你在使用時,可以想想看,你要什麼樣的效果,再想想看要使用什麼樣的資料結構才會讓你在讀取上和運算上加快!
如果你在Optimization上有疑問,就可以來比較一下;譬如有一些不同的data structure, 實在不知道誰比較好,可以來用這個elm-benchmark來做測試。其實用起來很像elm-test。
import Array
import Arry.Hamt as Hamt
import Benchmark exposing (..)
suite : Benchmark
suite =
let
sampleArray =
Hamt.initialize 100 identity
in
describe "Array.Hamt"
[ -- nest as many descriptions as you like
describe "slice"
[ benchmark "from the beginning" <|
\_ -> Hamt.slice 50 100 sampleArray
, benchmark "from the end" <|
\_ -> Hamt.slice 0 50 sampleArray
]
-- compare the results of two benchmarks
, Benchmark.compare "initialize"
"HAMT"
(\_ -> Hamt.initialize 100 identity)
"core"
(\_ -> Array.initialize 100 identity)
]
只要記得常用的三個function: describe
, benchmark
, compare
就可以做簡單的比較了。
這個是Elm Html module裡的功能。如果你有一個比較大的view, 每次都要重新render也是很麻煩,你就可以用這個 lazy
來讓電腦記住,只有在改變時才重新render,但這樣也是有代價的,譬如會秏比較多的記憶體。所以不要在每一個view裡都用Html.lazy,一切都是有代價的…
viewMenu : List MenuItem -> Html Msg
viewMenu items =
-- lots of code here
view : Model -> Html Msg
view model =
-- codes
lazy viewMenu model.menuItems