Jus*_*ser 5 polymorphism algebraic-data-types elm
我有一些记录类型结构基本上像这样:
type Body x = { x | pos: (Int,Int) }
type Bubble = Body { radius: Int }
type Box = Body { width: Int, height: Int }
Run Code Online (Sandbox Code Playgroud)
现在我想有一个混合列表中的任何一个并执行部分操作Body,但仍然是特殊情况处理Box和Bubble其他时间.例如,有(实现省略):
mv: (Int,Int) -> Body a -> Body a
bubble: Bubble
box: Box
Run Code Online (Sandbox Code Playgroud)
我想要
map (mv (1,1)) [box,bubble]
Run Code Online (Sandbox Code Playgroud)
但这失败了,因为Elm认为列表中的类型不兼容.
现在我可以将Boxes和Bubbles 包装在ADT中,如下所示:
type BodyWrap = BoxWrap Box | BubbleWrap Bubble
Run Code Online (Sandbox Code Playgroud)
但是我需要在每种情况下进行解包和重新打包.如果我想在混合列表上折叠,它会变得更加混乱.这个要点就是一个例子.
有没有更优雅的方式来处理这种情况?
使用组合而不是继承时,这个问题就消失了.
不是将整个结构包装在ADT中,而是使记录中的一个字段保持具有特定于对象的属性的ADT:
type Body = { pos: (Int,Int), shape: Shape }
data shape = Bubble Int | Box (Int,Int)
Run Code Online (Sandbox Code Playgroud)
这允许Body在shape仅在必要时匹配时使用共享结构.