如何将 elm-monocle 与 sum 类型一起使用?

Posted

技术标签:

【中文标题】如何将 elm-monocle 与 sum 类型一起使用?【英文标题】:How do I use elm-monocle with a sum type? 【发布时间】:2020-11-02 22:24:15 【问题描述】:

如何编写访问记录中的字段的镜头,该记录本身在 sum 类型中?

我有一个这样的模型:

type alias Coords =
   x : Maybe String
  , y : Maybe String
  

type alias Foo =
   coords : Maybe Coords
  

type alias Bar =
   coords : Maybe Coords
  

type Thing = FooThing Foo | BarThing Bar

type alias Model =
   thing : Maybe Thing
  

我知道我可以访问Model 中的Thing

thingLens : Optional Model Thing
thingLens = Optional .thing (\b a ->  a | thing = Just b )

...我相信我可以从Foo 获得x

xFromFoo : Optional Thing String
xFromFoo = Optional .x (\b a ->  a | x = b )

...但是我该如何编写这些?我想从Model 转到Foo 内的x

【问题讨论】:

【参考方案1】:

经过一些实验,我想出了这个,它有效:

thingL : Optional Model Thing
thingL = Optional .thing (\b a ->  a | thing = Just b )

thingFooCoordsL : Optional Thing Coords
thingFooCoordsL =
  let get a = case a of
        FooThing f -> f.coords
        _ -> Nothing
      set val thing = case thing of
        FooThing f ->
          FooThing  f | coords = Just val 
        a -> a
   in Optional get set

coordsXL : Optional Coords String
coordsXL = Optional .x (\b a ->  a | x = Just b )

fooThingCoordsXL : Optional Model Title
fooThingCoordsXL = thingL
  |> Monocle.Compose.optionalWithOptional thingFooCoordsL
  |> Monocle.Compose.optionalWithOptional coordsXL

基本上,您需要一个封装和展开 sum 类型的镜头,并且您需要为每个要访问的 sum 类型的构造函数使用不同的镜头。

【讨论】:

以上是关于如何将 elm-monocle 与 sum 类型一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用不同类型的流减少?

sum 函数语法与应用

理解数据类型与数学运算:求和温度转换

理解数据类型与数学运算:求和温度转换

理解数据类型与数学运算:求和温度转换

理解数据类型与数学运算:求和温度转换