H!
假设我有一个抽象类机器人,有几个属性,如'position'和'weight'.这个抽象类实现了三个方法:'take','drop'和'move',但也有一个抽象方法'makeAction'.然后我有两个名为'TRobot'和'FRobot'的子机器人.基本上,TRobot和FRobot将实现'makeAction'方法,但不会重新实现'take','drop'和'move'.
我的问题是你如何在Haskell中做到这一点.
我从数据类型开始:
data Robot = Robot {position :: Char, weight :: Int}
Run Code Online (Sandbox Code Playgroud)
编辑:
但我想函数'take','move'和'drop'(take :: Box - > Robot - > Robot)如果Robot是TRobot或FRobot则表现相同.
但是,功能
makeAction :: Robot -> Action
Run Code Online (Sandbox Code Playgroud)
无论Robot是TRobot还是FRobot都应该有不同的实现.
谢谢您的帮助.
Mat*_*hid 15
我有<在这里插入面向对象的设计>.如何在非OO语言(如Haskell)中实现它?
呃......这不是一个好主意.这很可能是远不如退后一步并解释什么你实际上是试图实现.Haskell需要一种完全不同的思考软件设计的方式.在不知道你真正想做什么的情况下,很难确切地知道实现它的最佳方式是什么.
特别是:两种机器人实际上有何不同?它们如何相似?
可能是您只想构建单个数据类型的构造函数(如您所编写的),其中每个move函数的行为都不同,而take/ drop不关心的函数.或者你可能只想要一个构造函数,其中一个字段可以说明它是哪种机器人类型.或许你真的想要两个完全独立的类型.如果不了解更多关于你想要做什么的话,很难说.
在Haskell 中有很多方法可以做到这一点,但是你必须首先理解传统的"类"并不直接对应于任何Haskell结构.
你可以很容易地做这样的事情:
data Robot = Robot {
position :: Char,
weight :: Int,
makeAction :: Robot -> String
}
Run Code Online (Sandbox Code Playgroud)
这里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 = …
Run Code Online (Sandbox Code Playgroud)
请注意,Robot TRobot并Robot FRobot有不同的类型,所以如果你需要一个通用的机器人类型,你有存在类型做:
data AnyRobot = forall a. RobotType a => AnyRobot (Robot a)
Run Code Online (Sandbox Code Playgroud)
基本上,因为我们在类型系统中存储TRobot和FRobot之间的差异,我们需要存在类型以允许我们在运行时访问这些差异(因为类型在编译时被删除).