首页 > 解决方案 > Haskell 多重声明错误类型“Shape”

问题描述

我试图创建一个名为的总和类型Shape,然后在另一个以PositionedShapeShape init 的属性命名的总和类型上

data Shape = Circle Float |
             Rectangle Float Float

area :: Shape -> Float
area (Circle r)      = pi * r * r
area (Rectangle h w) = h * w

data Point = Point Float Float
             deriving (Eq,Show )


data PositionedShape = Circle Point Float |
                       Rectangle Point Float Float
                       deriving (Eq,Show)

在我看来,这似乎是正确的,但它一直在说多个声明。

Week7.hs:92:24: error:
    Multiple declarations of ‘Circle’
    Declared at: Week7.hs:26:14
                 Week7.hs:92:24

   |
92 | data PositionedShape = Circle Point Float |
   |                        ^^^^^^^^^^^^^^^^^^

Week7.hs:93:24: error:
    Multiple declarations of ‘Rectangle’
    Declared at: Week7.hs:27:14
                 Week7.hs:93:24
   |
93 |                        Rectangle Point Float Float
   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^

标签: haskell

解决方案


正如错误消息所说,您已经Circle多次Rectangle声明。在 Haskell 中,数据构造函数必须具有唯一的名称,至少在同一个模块中。

您可以通过为数据构造函数提供明确的名称来解决此问题,例如:

data PositionedShape = PositionedCircle Point Float |
                       PositionedRectangle Point Float Float
                       deriving (Eq,Show)

数据构造函数也可以用作函数。例如,您可以将PositionedCircle其视为一个函数:

Prelude> :t PositionedCircle
PositionedCircle :: Point -> Float -> PositionedShape

Point您可以使用 a和值调用它Float

Prelude> PositionedCircle (Point 1 2) 3
PositionedCircle (Point 1.0 2.0) 3.0

函数名必须是唯一的,否则编译器不知道你指的是哪一个。这就是数据构造函数必须具有明确名称的原因。


看来您真正要解决的问题是如何将位置与形状相关联,这样做可能会更好:

data PositionedShape = PositionedShape Point Shape deriving (Eq, Show)

您可以像这样使用这种替代方法:

Prelude> PositionedShape (Point 1 2) (Circle 3)
PositionedShape (Point 1.0 2.0) (Circle 3.0)

推荐阅读