Data structures 向组件传递道具的Elm/功能方式

Data structures 向组件传递道具的Elm/功能方式,data-structures,functional-programming,elm,Data Structures,Functional Programming,Elm,我不熟悉Elm和函数式编程。我正在构建一个费用跟踪应用程序,其模型如下: initialModel = { expenseTransactions = [ { date = Date.fromString "2016/10/23" , transactions = [ { id = 1 , amount = 17.54 , description = "

我不熟悉Elm和函数式编程。我正在构建一个费用跟踪应用程序,其模型如下:

initialModel =
    { expenseTransactions =
        [ { date = Date.fromString "2016/10/23"
          , transactions =
              [ { id = 1
                  , amount = 17.54
                  , description = "stuff"
                  , category = 3
                  }
                , { id = 2
                  , amount = 15.0
                  , description = "things"
                  , category = 4
                  }
              ]
          }
      ],
      expenseCategories =
        Dict.fromList [ ( 1, "Rent" ), ( 2, "Groceries" ), ( 3, "Eating out" ) ]
    }
在我看来,我使用的是一个
renderExpensesTable
函数,该函数依次调用
renderexpensesforone-day
函数,该函数依次调用
renderExpensesRow
函数

我要做的是将事务的
类别一直存储为一个数字,然后通过在其他语言中执行类似于
ExpenseCompositions[transaction.category]
的操作从视图中引用其名称。(如果我只是将类别存储为一个字符串,如
“Groceries”,我就会得到这个结果)
这个问题没有实际意义,但我想将
类别作为一个数字存储在模型中,然后单独引用它的原因是,用户将能够编辑类别名称,并且我不想每次都必须更新模型中的每个事务,如果我存储
,我就必须这样做>类别
作为字符串。)

我意识到我必须将
支出类别
视图
方法向下传递到每个级别(
renderExpensesTable
renderexpensesforone day
,等等)

这不起作用,我认为这是因为我可能不应该尝试使用
List.map2
来实现这一点。在我尝试通过分类之前,我成功地通过了
map
,这是我尝试将它们与其他东西(如React中的道具)一起通过的


做这种事的理想“榆树方式”是什么?如果我们不能直接访问模型,并且没有React风格的道具,那么我们应该如何处理模型中有两个不同部分需要引用的情况,例如
expenseTransactions
ExpenseComposes

为什么不在同一个模型中存储单独的类别结构

比如:

类型模型=
模型{支出交易:tl
,支出类别:Dict.fromList[(1,“租金”),(2,“杂货”),(3,“外出就餐”)]
最后,您的所有视图功能都将采用此巨型模型:

viewwhere:Model->Html Msg
ViewWhather=。。。
我仍然不知道如何通过模型。每个渲染函数都通过List.map连接到下一个渲染函数,而且由于该函数只将列表作为参数,因此如何传递模型

可以修改这些渲染函数以将模型作为其第一个参数。例如:

renderexpensesforone-day:Model->expensesforneday->List String->Html msg
...
renderExpensesTable:Model->List ExpenseSforeDay->List String->Html消息
...
List.map2(renderExpensesForOneDay模型)天(Dict.values类别)

请注意,在上面的最后一句话中,我们是如何将一个curry函数(
renderExpensesForOneDay model
)传递给List.map2.

谢谢,但我不确定这是否回答了这个问题,尽管我可能还没有意识到,因为我是初学者,根本不理解您的答案。我应该更清楚:我不是在寻找改变模式的方法;我只想在视图中显示来自模型的信息。当这些信息来自模型中的一个地方时,比如
expenseTransactions
,这很简单,因为我可以将其作为参数传递,但是当这些信息来自两个地方时(比如
expenseTransactions
ExpenseComplements
),我不知道怎么做。感谢更新。我实际上已经把它们放在同一个模型中了,希望在我编辑后的原始帖子中能更清楚地看到。我的问题是,我不知道如何在成功使用诸如
List.map
@sebu之类的东西时,通过3层组件向下传递模型的两个位-如何将整个模型传递给每个渲染(视图)函数?否则,我不太清楚你到底在问什么。好吧,现在我们在同一页:)我想我可以这样做——我想我只是认为这是一种不好的做法,因为这会涉及传递大量不必要的信息(里面还有其他东西,比如收入交易,与
费用表
无关)。这是“最佳实践”吗方法?或者可能没有其他方法…?建议您在单个模型中表示应用程序的整个状态。性能不应因使用而受到显著影响。顺便说一句,渲染函数的类型定义不正确。它们应使用dict,而不是list作为第二个参数。I originally这样做了,但后来我故意使用了一个列表,因为我不能同时将列表和dict传递给任何
map
函数。它们只接受一种类型。
renderExpenseRow : ExpenseTransaction -> List String -> Html msg
renderExpenseRow transaction categories =
    -- ... row stuff ...

renderExpensesForOneDay : ExpensesForOneDay -> List String -> Html msg
renderExpensesForOneDay day categories =
    let
        dayTransactions =
            List.map2 renderExpenseRow day.transactions categories
    in
        -- ... yada yada ...
        dayTransactions

renderExpensesTable : List ExpensesForOneDay -> List String -> Html msg
renderExpensesTable days categories =
    let
        renderedDays =
            List.map2 renderExpensesForOneDay days (Dict.values categories)
    in
        div [ class "expenses-table" ] renderedDays