编译器对可组合记录感到困惑

时间:2016-10-22 09:56:39

标签: elm

鉴于这些类型别名

type alias Point =
    { x : Float
    , y : Float
    }

type alias ShapeProperties =
    { p1 : Point
    , p2 : Point
    }


type alias FillProperties a =
    { a | fill : Bool }


type alias FillShapeProperties =
    FillProperties ShapeProperties

和这些功能

test1 : FillShapeProperties → Bool
test1 properties =
    if properties.p1.x == 0 then
        properties.fill
    else
        False

test2 : FillShapeProperties → Bool
test2 properties =
    if originX properties == 0 then
→         properties.fill
    else
        False

originX : ShapeProperties → Float
originX shape = 
    Basics.min shape.p1.x shape.p2.x

test1编译,但test2

错误消息:

`properties` is being used in an unexpected way.

222|         properties.fill
             ^^^^^^^^^^
Based on its definition, `properties` has this type:

    { p1 : ..., p2 : ... }

But you are trying to use it as:

    { b | fill : ... }

test2的定义中,我清楚地说它是FillShapeProperties所以它应该知道它是{ p1 : ..., p2 : ..., fill: ... },不是吗?在test1,它知道...

这与在originX中使用test2以及在那里用作简单ShapeProperties的事实有关。那么这里发生了什么,我能做些什么呢?

1 个答案:

答案 0 :(得分:1)

FillShapePropertiesShapeProperties的记录类型不同,即使它们共享公共字段。

如果扩展FillShapeProperties的定义,则相当于:

type alias FillShapeProperties =
    { p1 : Point
    , p2 : Point
    , fill : Bool
    }

如果你想让你的代码更通用一些,你可以为“像形状”之类的东西做一个别名:

type alias ShapeLike a =
    { a
        | p1 : Point
        , p2 : Point
    }

然后,您可以将originX的签名更改为接受ShapeLike a,您的示例将正常编译:

originX : ShapeLike a -> Float
originX shape = 
    Basics.min shape.p1.x shape.p2.x