Oop Haskell中表示的OO类
啊 假设我有一个抽象类Robot,它有一些属性,比如“position”和“weight”。这个抽象类实现了三个方法:“take”、“drop”和“move”,但也有一个抽象方法“makeAction”。然后我有两个子类“Robot”,分别是“TRobot”和“FRobot”。基本上,TRobot和FRobot将实现“makeAction”方法,但不会重新实现“take”、“drop”和“move”。Oop Haskell中表示的OO类,oop,haskell,Oop,Haskell,啊 假设我有一个抽象类Robot,它有一些属性,比如“position”和“weight”。这个抽象类实现了三个方法:“take”、“drop”和“move”,但也有一个抽象方法“makeAction”。然后我有两个子类“Robot”,分别是“TRobot”和“FRobot”。基本上,TRobot和FRobot将实现“makeAction”方法,但不会重新实现“take”、“drop”和“move”。 我的问题是在Haskell你是如何做到这一点的。 我从数据类型开始: data Robot
我的问题是在Haskell你是如何做到这一点的。
我从数据类型开始:
data Robot = Robot {position :: Char, weight :: Int}
编辑:
但是,如果Robot是TRobot或FRobot,我希望函数“take”、“move”和“drop”(take::Box->Robot->Robot)的行为相同。
然而,功能
makeAction :: Robot -> Action
无论Robot是TRobot还是FRobot,都应该有不同的实现
感谢您的帮助。Haskell没有与OO语言相同的子类型。通常,如果需要这种类型的子类型多态性,可以使用具有高阶函数的数据类型作为字段。不过,在这种情况下,似乎没有必要这样做 以下是我的做法:
data RobotType = TRobot | FRobot
data Robot = Robot {
robotType :: RobotType
,position :: Char
,weight :: Int
}
Haskell不像OO语言那样具有子类型。通常,如果需要这种类型的子类型多态性,可以使用具有高阶函数的数据类型作为字段。不过,在这种情况下,似乎没有必要这样做 以下是我的做法:
data RobotType = TRobot | FRobot
data Robot = Robot {
robotType :: RobotType
,position :: Char
,weight :: Int
}
在Haskell中有很多方法可以做到这一点,但您必须首先了解传统的“类”并不直接对应于任何Haskell构造
您可以非常轻松地执行以下操作:
data Robot = Robot {
position :: Char,
weight :: Int,
makeAction :: Robot -> String
}
这里,makeAction
是一个字段,它包含TRobot
和FRobot
类型的不同函数。有很多更复杂的方法可以做到这一点,比如类型类、GADT、组合等等,但这将帮助您开始
类型类版本
这是一种不同的方法,更复杂
以下是普通类型类的版本:
-- The robot type is expressed using a type parameter (called "a")
data Robot a = Robot {
position :: Char,
weight :: Int
}
-- All robot types have their own "makeAction" function
class RobotType a where
makeAction :: Robot a -> String
data TRobot
instance RobotType TRobot where
makeAction robot = ...
data FRobot
instance RobotType FRobot where
makeAction robot = …
请注意,Robot-TRobot
和Robot-FRobot
是不同的类型,因此如果需要泛型Robot类型,则必须使用存在类型:
data AnyRobot = forall a. RobotType a => AnyRobot (Robot a)
基本上,因为我们在类型系统中存储TRobot和FRobot之间的差异,所以我们需要存在类型来允许我们在运行时访问这些差异(因为类型在编译时被删除)。在Haskell中有很多方法可以做到这一点,但您必须首先了解传统的“类”不要直接对应于任何Haskell构造
您可以非常轻松地执行以下操作:
data Robot = Robot {
position :: Char,
weight :: Int,
makeAction :: Robot -> String
}
这里,makeAction
是一个字段,它包含TRobot
和FRobot
类型的不同函数。有很多更复杂的方法可以做到这一点,比如类型类、GADT、组合等等,但这将帮助您开始
类型类版本
这是一种不同的方法,更复杂
以下是普通类型类的版本:
-- The robot type is expressed using a type parameter (called "a")
data Robot a = Robot {
position :: Char,
weight :: Int
}
-- All robot types have their own "makeAction" function
class RobotType a where
makeAction :: Robot a -> String
data TRobot
instance RobotType TRobot where
makeAction robot = ...
data FRobot
instance RobotType FRobot where
makeAction robot = …
请注意,Robot-TRobot
和Robot-FRobot
是不同的类型,因此如果需要泛型Robot类型,则必须使用存在类型:
data AnyRobot = forall a. RobotType a => AnyRobot (Robot a)
基本上,因为我们将TRobot和FRobot之间的差异存储在类型系统中,所以我们需要存在类型来允许我们在运行时访问这些差异(因为类型在编译时被删除)。您正在尝试这样做,这是在OO语言中进行此类操作的主要方式,但是Haskell不支持这一点
相反,Haskell主要通过使用来完成相同的事情。如果你以前从未听说过,我建议你要么读,要么读
因为我真的想回答你的问题,所以你得到你想要的行为的方式是这样的:
class Robot r where
position :: r -> Char
weight :: r -> Int
makeAction :: -- ?? You didn't say.
data FRobot = FRobot { frPosition :: Char, frWeight :: Int }
instance Robot FRobot where
position = frPosition
weight = frWeight
makeAction = -- Whatever you wanted.
class Robot r where
position :: r -> Char
weight :: r -> Int
makeAction :: -- ?? You didn't say.
data FRobot = FRobot { frPosition :: Char, frWeight :: Int }
instance Robot FRobot where
position = frPosition
weight = frWeight
makeAction = -- Whatever you wanted.
Robot r=>r->…
,并使r成为任何类型的Robot。如果不想实现某个方法,可以将其定义为错误
或未定义
,但请注意,这是不安全和不可取的行为
编辑:如果您希望makeAction对不同的机器人具有不同的类型。。。您可能会减少到重复,因为没有其他方法可以轻松地将其适应到类型系统中。如果你能给我们提供更多的信息,我可能会提出更具体的建议。你正在尝试这样做,这是在OO语言中做这类事情的主要方式,但Haskell不支持这一点
相反,Haskell主要通过使用来完成相同的事情。如果你以前从未听说过,我建议你要么读,要么读
因为我真的想回答你的问题,所以你得到你想要的行为的方式是这样的:
class Robot r where
position :: r -> Char
weight :: r -> Int
makeAction :: -- ?? You didn't say.
data FRobot = FRobot { frPosition :: Char, frWeight :: Int }
instance Robot FRobot where
position = frPosition
weight = frWeight
makeAction = -- Whatever you wanted.
class Robot r where
position :: r -> Char
weight :: r -> Int
makeAction :: -- ?? You didn't say.
data FRobot = FRobot { frPosition :: Char, frWeight :: Int }
instance Robot FRobot where
position = frPosition
weight = frWeight
makeAction = -- Whatever you wanted.
Robot r=>r->…
,并使r成为任何类型的Robot。如果不想实现某个方法,可以将其定义为错误
或未定义
,但请注意,这是不安全和不可取的行为
编辑:如果您希望makeAction对不同的机器人具有不同的类型。。。您可能会减少到重复,因为没有其他方法可以轻松地将其适应到类型系统中。如果您能给我们提供更多的信息,我可能会提出更具体的建议。作为