为什么在不同类型的构造函数中不允许使用同名的数据构造函数?


11

以下声明给出了一个错误:

type Vec2d = (Float, Float)
type Vec3d = (Float, Float, Float)
-- Rect x y defines a rectangle spanning from (0,0) to (x,y)
data Obj2d = Rect Float Float
           | Translate Vec2d Obj2d
-- Cuboid x y z defines a cuboid spanning from (0,0,0) to (x,y,z)
data Obj3d = Cuboid Float Float Float
           | Translate Vec3d Obj3d

Multiple declarations of 'Translate'

现在,我想知道为什么引入了此限制?

如果没有限制,可以写

Translate (1, 1) Rect 2 2Translate (1, 2, 3) Cuboid 1 1 1,听起来自然。

我没有(立即)看到这种情况如何导致解析问题竞标以不允许使用相同的名称,类型可以由参数推断(Rect 2 2Obj2dCuboid 1 1 1Obj3d)。

我敢肯定,语言设计师选择一个很好的理由是不允许不同类型的数据构造函数使用相同的名称,但是我想学习:为什么,当没有明显必要时?

(而且类型歧义消除是Haskell的头等大事!)


3
关于由参数推断的类型:您是否知道有时从函数的类型推断参数的类型?

@delnan我不知道...听起来像是对我的答案。我一直认为推断是自下而上的,尽管我可以看到使用类型图另一侧的类型信息来解决歧义,正如您所描述的那样,这是决定性因素...我的想法是返回值类型位于底部顶部是图形和函数调用,分辨率是从底部向上折叠形成的聚合,但这不是全部,您在说什么?毫不奇怪,使用完全推论的依存类型语言,这可能更准确。.–
Jimmy Hoffa

Answers:


13

这是因为数据构造函数只是函数,而Haskell不允许函数重载。如果使用GADT语法定义类型,可能会更清楚:

{-# LANGUAGE GADTs #-}
data Obj2d where
    Rect :: Float -> Float -> Obj2d   -- a function from floats to obj2d's
    Translate :: Vec2d -> Obj2d       -- a function from vec2d's to Obj2d's

我相信他们(GHC开发人员)正在努力解决此问题,包括type class为共享同一数据构造函数或类似数据的所有类型引入新的。因此,请继续关注,您的问题可能很快就会解决!(我希望)


我绝对期待type class您指定的这些构造。-原因是:我没有问题,我可以Translate2Translate3d,但是我不想污染名称空间。
2014年

我不是GHC开发人员,所以只是说说而已。我希望它也会发生。
bstamour 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.