在Elm中处理具有共享子结构的记录 [英] Handling records with shared substructure in Elm

查看:94
本文介绍了在Elm中处理具有共享子结构的记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些基本上像这样的记录类型:

I have some record types structured essentially like this:

type Body x = { x | pos: (Int,Int) }
type Bubble = Body { radius: Int }
type Box = Body { width: Int, height: Int }

现在,我想将所有这些混合在一起,并在Body部分上执行一些操作,但在其他时候还是特殊情况下处理BoxBubble.例如,(取消实现):

Now I would like to have a mixed list of any of these and perform some operation on the Body part, but still special case handling Box and Bubble other times. For example, having (implementations elided):

mv: (Int,Int) -> Body a -> Body a
bubble: Bubble
box: Box

我想

map (mv (1,1)) [box,bubble]

但这失败了,因为Elm认为列表中的类型不兼容.

but this fails because Elm deems the types in the list incompatible.

现在,我可以将Box es和Bubble s包裹在ADT中,如下所示:

Now I could wrap the Boxes and Bubbles in an ADT like so:

type BodyWrap = BoxWrap Box | BubbleWrap Bubble

但是然后我需要在每种情况下都进行拆包和重新包装.如果我想在混合清单上折,它会变得更加混乱. 此要点.

but then I need to do an unwrapping and rewrapping in every case. If I want to fold on the mixed list it gets even messier. An example is in this gist.

有没有更优雅的方式来处理这种情况?

Is there a more elegant way of handling this situation?

推荐答案

使用组合而不是继承时,此问题就消失了.

This problem goes away when using composition rather than inheritance.

不是将整个结构包装在ADT中,而是使记录中的一个字段容纳具有对象特定属性的ADT:

Instead of wrapping the whole structure in an ADT, make one field in the record hold an ADT with the object-specific properties:

type Body = { pos: (Int,Int), shape: Shape }
data shape = Bubble Int | Box (Int,Int)

这允许使用Body中的共享结构,同时仅在必要时在shape上进行匹配.

This allows using the shared structure in Body while matching on shape only when necessary.

这篇关于在Elm中处理具有共享子结构的记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆