Elm中的建模关联导致依赖循环

Ale*_*xHv 4 circular-dependency associations elm

我的数据库包含一个项目表和一个关联广告表.

我希望我的elm应用程序显示包含其关联广告的项目,或显示包含父项目信息的广告.

为了满足这些接口需求,我本来希望在elm中编写以下两个模块,匹配我的API已发送的内容:

module Item.Model exposing (..)

import Ad.Model exposing (Ad)

type alias Item =
   { ads : Maybe List Ad
   }
Run Code Online (Sandbox Code Playgroud)

module Ad.Model exposing (..)

import Item.Model exposing (Item)

type alias Ad =
   { item : Maybe Item
   }
Run Code Online (Sandbox Code Playgroud)

但是,此定义会导致以下依赖项循环错误:

ERROR in ./elm-admin/Main.elm
Module build failed: Error: Compiler process exited with error Compilation failed
Your dependencies form a cycle:

  ???????
  ?    Item.Model
  ?     ?
  ?    Ad.Model
  ???????

You may need to move some values to a new module to get rid of the cycle.

    at ChildProcess.<anonymous> (/opt/app/assets/node_modules/node-elm-compiler/index.js:141:27)
    at emitTwo (events.js:106:13)
    at ChildProcess.emit (events.js:191:7)
    at maybeClose (internal/child_process.js:886:16)
    at Socket.<anonymous> (internal/child_process.js:342:11)
    at emitOne (events.js:96:13)
    at Socket.emit (events.js:188:7)
    at Pipe._handle.close [as _onclose] (net.js:497:12)
 @ ./js/admin.js 3:12-44
Run Code Online (Sandbox Code Playgroud)

看起来type alias在同一模块中定义两者并不会使编译器停止,但这对我来说不是一个令人满意的解决方案,因为我不希望Model我的每个应用程序都在同一个文件中.

有没有办法解决这个问题,而不定义两个类型的别名Ad,并Item在同一模块中?

Sim*_*n H 5

我想不出你提出的问题的直接解决方案,但我不会以这种方式存储数据 - 我会使用指针代替

module Item.Model exposing (..)

type alias Items = Dict String Item

type alias Item =
   { ads : List String
   }
   -- you don't need a Maybe and a List 
   -- as the absence of data can be conveyed by the empty list
Run Code Online (Sandbox Code Playgroud)

module Ad.Model exposing (..)

import Item.Model exposing (Item)

type alias Ads = Dict String Ad 

type alias Ad =
   { itemKey : Maybe String
   }
Run Code Online (Sandbox Code Playgroud)

然后你就可以这样了

model.ads 
    |> L.filterMap (\key -> Dict.get key model.items)
    |> ...

model.itemKey
    |> Maybe.andThen (\itemKey -> Dict.get itemKey model.ads)
    |> ...
Run Code Online (Sandbox Code Playgroud)

这种方法有效,并且随后也提供了备忘的机会