elm - 在函数中执行多行

时间:2016-05-08 15:33:53

标签: functional-programming elm side-effects

在榆树中,有类似下面的可能

foo : Int -> Html
foo inputNum =
  addToNumHistory inputNum ;
  display inputNum

上面的目的是执行多行代码吗?

如果没有,这是因为以上是副作用的一个例子吗?

如果上述语法不可能,那么如何同时执行两个函数/代码行,如上所述,或作为给定输入(case分支)的结果?

修改

以上是一个不好的例子。以下使用Elm Architecture:

--Model
type alias Model =
  { number : Int
  , numberHistory : List Int
  }

type Action
  = Number Int


--Update
update : Action -> Model
update action =
  case action of
    Number num->
      addToNumHistory num           

addToNumHistory : Int -> Model -> Model 
addToNumHistory num modelHistory =
  { model 
    | number = num
    , numberHistory = num :: model.numberHistory
  }

--View     
view : Signal.Address Action -> Model -> Html
view action model =
  div []
    [  field 
       "text" 
       address 
       Number model.number
       "Enter lucky number here pal!"
       model.number 
    ]

鉴于此,我正确地假设要以改变底层模型的方式“执行多行”,人们只需使用/扩展模型 - 例如,实现类似于以下的变更:

--Update
update : Action -> Model
update action =
  case action of
    Number num->
      addToNumHistory num;
      addToChangeHistory

只需按如下方式扩展模型:

--Model
type alias Model =
  { number : Int
  , numberHistory : List Int
  , changeHistory : List Date
  }

--Update
update : Action -> Model
update action =
  case action of
    Number num->
      addToNumHistoryWithChangeHistory num

addToNumHistoryWithChangeHistory : Int -> Model -> Model 
addToNumHistory num modelHistory =
  { model 
    | number = num
    , numberHistory = num :: model.numberHistory
    , changeHistory = getCurrentDate :: model.changeHistory
  }

getCurrentDate : Date

1 个答案:

答案 0 :(得分:2)

在这种特殊情况下,您不需要有副作用。

我必须添加两个实用程序函数来创建一个有效的示例。

  • onInput处理'input'事件
  • parseIntInt
  • 检索String

其余部分是0.16

的基本Elm Architecture生命周期

请考虑我为StartApp.Simple使用的最小例子:

import Html exposing (text, input, div, Html, Attribute)
import Html.Attributes exposing (value)
import Html.Events exposing (on, targetValue)
import String
import Signal exposing (Address)
import StartApp.Simple as StarApp


--Utils
onInput : Address a -> (String -> a) -> Attribute
onInput address f =
  on "input" targetValue (\v -> Signal.message address (f v))


parseInt : String -> Int
parseInt string =
  case String.toInt string of
    Ok value ->
      value

    Err error ->
      0


--Model
type alias Model =
  { number : Int
  , numberHistory : List Int
  }


initModel : Model
initModel =
  { number = 0
  , numberHistory = []
  }


--Update


type Action
  = UpdateNumber String


update : Action -> Model -> Model
update action model =
  case action of
    UpdateNumber num -> 
       addToNumHistory (parseInt num) model


addToNumHistory : Int -> Model -> Model 
addToNumHistory num model =
  { model 
    | number = num
    , numberHistory = num :: model.numberHistory
  }


--View     
view : Signal.Address Action -> Model -> Html
view address model =
  div
    []
    [ input
        {- On every 'input' event,
           grab the value of input field and send to UpdateNumber
        -}
        [ onInput address UpdateNumber, value (toString model.number) ]
        []
    , div [] [ text (toString model.number) ]
    , div
        []
        ( model.numberHistory
          |> List.reverse
          |> List.map (toString)
          |> List.map text
        )
    ]


main : Signal Html
main =
  StarApp.start
    { view = view
    , update = update
    , model = initModel
    }