在Haskell中实现函数重载 我正在编写类似于C++程序的哈斯克尔代码的问题。 < C++代码是: class Rectangle { private: int length; int width; public: Rectangle() { length = 0; width = 0; } Rectangle(int x) { length = x; width =0; } Rectangle ( int x , int y) { length = x; width = y; } };

在Haskell中实现函数重载 我正在编写类似于C++程序的哈斯克尔代码的问题。 < C++代码是: class Rectangle { private: int length; int width; public: Rectangle() { length = 0; width = 0; } Rectangle(int x) { length = x; width =0; } Rectangle ( int x , int y) { length = x; width = y; } };,haskell,Haskell,为了编写类似的Haskell代码,我创建了一个数据类型矩形 data Rectangle = Rectangle Length Width deriving (Eq, Show , Read) type Length = Int type Width = Int 然后我想到了制作一个可以作为构造函数的加载函数。但我不明白如何用不同数量的参数实现函数重载。 请帮忙。谢谢。您可以使用记录语法来实现该行为 data Rectangle = Rectangle {len :: Length, widt

为了编写类似的Haskell代码,我创建了一个数据类型矩形

data Rectangle = Rectangle Length Width deriving (Eq, Show , Read)
type Length = Int
type Width = Int
然后我想到了制作一个可以作为构造函数的加载函数。但我不明白如何用不同数量的参数实现函数重载。
请帮忙。谢谢。

您可以使用记录语法来实现该行为

data Rectangle = Rectangle {len :: Length, width :: Width} deriving (Eq, Show , Read)
type Length = Int
type Width = Int

rectangle = Rectangle { len = 0, width = 0 }
rectangle::rectangle
将是您的构造函数

现在您可以定义一些
矩形
值:

λ> let a = rectangle {len = 1}

λ> a
Rectangle {len = 1, width = 0}
虽然可以在Haskell中执行这种重载,但它不被认为是惯用的,并且以后可能会导致混淆错误。相反,您只需定义构造数据的函数:

point :: Rectangle
point = Rectangle 0 0

line :: Length -> Rectangle
line l = Rectangle l 0

square :: Int -> Rectangle
square a = Rectangle a a
这使您能够给出清晰的名称来描述每个重载的语义,而不是依赖于为消除歧义而提供的参数的数量和类型

但是,如果您确实想编写重载版本,可以使用TypeClass轻松编写:

class MakeRectangle a where
  rectangle :: a

instance MakeRectangle Rectangle where
  rectangle = Rectangle 0 0

instance MakeRectangle (Length -> Rectangle) where
  rectangle l = Rectangle l 0

instance MakeRectangle (Length -> Width -> Rectangle) where
  rectangle = Rectangle
您需要将
{-#LANGUAGE FlexibleInstances#-}
放在文件顶部才能编译此文件。这样的把戏被标准库使用,但我不认为它是Haskell超载的一个特别好的例子;重载值的类型几乎总是有一些结构,而这里它的整个结构是由实例决定的,这可能会妨碍类型推断;不仅如此,还没有任何合理的法律来管理实例(事实上,该类型过于笼统,不允许任何实例)

但是如果你真的想这样做,你可以这样做,虽然这通常是个坏主意,但有时(比如
printf
)这是实现你想要的界面的唯一方法

要在GHCi中尝试此操作,您需要显式指定正在使用的类型,否则它将无法解析实例:

GHCi> rectangle :: Rectangle
Rectangle 0 0
GHCi> rectangle (1 :: Length) :: Rectangle
Rectangle 1 0
GHCi> rectangle (1 :: Length) (2 :: Width) :: Rectangle
Rectangle 1 2

你要找的不仅仅是:

data Rectangle = Point |  Line Int | Rectangle Int Int

我不能编译这个程序。错误是
矩形的多个声明
是否确保保留缩进?在文件的其他地方是否有另一个
矩形
声明?如果两者都不是,那么把你正在编译的完整文件添加到你的问题中,我来看看;Haskell是一种缩进敏感语言。你能解释一下有空格或没有空格会发生什么吗?没有空格,给定的
矩形
的定义被视为重复的顶级定义,而
实例
的定义是空的;在空间中,代码< >矩形> /COD>的定义与<代码>类< /代码>和<代码>实例< /C++ >声明一致。我不想尝试在C++之后对Haskell进行建模;这只会导致很多痛苦。还有,为什么第二个矩形构造函数是一条直线?我认为一个更合理的实现是默认为(1,1),如果得到一个int,则传入(x,x)以形成一个正方形。听说过构造函数初始化列表吗?@VladLazarenko:听说过仍在学习的人吗?(提示:你是其中之一,每个人都是)