其實我大概都是一邊寫,一邊想想看接下來幾天到底要寫什麼。已經寫了20篇了。大致的elm的介紹,寫到這已經都差不多了。(我知道我省略很多functional programming的基礎),其實今年的鐵人賽也有不少人寫functional programming,有用javascript的,也有scala,還有elixir,所以我把整個重心都放在elm的應用上面,接下來幾天我想寫關於elm在stackoverflow上最常被關注的問題,如果還有時間接下來幾天再寫個elm的實戰,完成這一系列。
線上互動的code
import Html exposing (..)
import Html.Events exposing (onClick)
import Time exposing (..)
import Date
import Task
main =
Html.program
{ init = { message = "Click the button to see the time" } ! []
, view = view
, update = update
, subscriptions = \_ -> Sub.none
}
type alias Model = { message: String }
view model =
div []
[ button [ onClick FetchTime ] [ text "Fetch the current time" ]
, div [] [ text model.message ]
]
type Msg
= FetchTime
| Now Time
update msg model =
case msg of
FetchTime ->
model ! [ Task.perform Now Time.now ]
Now t ->
{ model | message = "The date is now " ++ (toString (Date.fromTime t)) } ! []
這裡有用上了兩個和時間有關的,一個是 Time
, 一個是 Date
, 因為要 取得時間
這件事是有副作用的,也就是會破壞純粹性,因為現在的時間一直在變,所以我們的取得的時間也一直在變,這樣怎麼做?怎麼可能會是 pure
呢?這有點像是 haskell 的 IO
,不過已超過我們的範圍太多,但在elm裡就是用 Task
或是 Program
。你在你的 update
用 Cmd
給了個 Task
給 Elm Architecture
,在 Elm architecture
裡,他會幫你做一些事情,然後返還給你的,仍然在functional programming的pure保證內,也就是說, Task
或是 Program
可以讓你做一些會有side effect的事情,但仍然可以保持 pure。
-- Task module
type alias Task err ok = Task err ok
perform : (a -> msg) -> Task Never a -> Cmd msg
-- Time module
Time.now : Task x Time
-- perform Time.now
Task.perform Now Time.now
我試著來說明一下,先來看看 perform
這個會去讓 Task
在 elm runtime
執行。 (a -> msg)
這個就是要放入 update
Type的其中一個,像我們這個例子是取名 Now
, 而 Time.now
會執行成Taske x Time
, 而這個 x type 在perform裡是個 Never
type。
而為了讓這個時間轉變成日期,我們需要把這時間從 Task x Time
裡取出來,因為我們在 update
裡還要加一個把 t
取出來的方式,才可以讓 fromTime : Time -> Date
發揮作用。