Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop Haskell中表示的OO类_Oop_Haskell - Fatal编程技术网

Oop Haskell中表示的OO类

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

假设我有一个抽象类Robot,它有一些属性,比如“position”和“weight”。这个抽象类实现了三个方法:“take”、“drop”和“move”,但也有一个抽象方法“makeAction”。然后我有两个子类“Robot”,分别是“TRobot”和“FRobot”。基本上,TRobot和FRobot将实现“makeAction”方法,但不会重新实现“take”、“drop”和“move”。

我的问题是在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主要通过使用来完成相同的事情。如果你以前从未听说过,我建议你要么读,要么读

因为我真的想回答你的问题,所以你得到你想要的行为的方式是这样的:

  • 创建一个类似于抽象类的typeclass,该抽象类定义类型必须实现的最低行为,以包含在此typeclass中:

    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.
    
  • 然后使每个类型都成为该typeclass的实例:

    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主要通过使用来完成相同的事情。如果你以前从未听说过,我建议你要么读,要么读

    因为我真的想回答你的问题,所以你得到你想要的行为的方式是这样的:

  • 创建一个类似于抽象类的typeclass,该抽象类定义类型必须实现的最低行为,以包含在此typeclass中:

    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.
    
  • 然后使每个类型都成为该typeclass的实例:

    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对不同的机器人具有不同的类型。。。您可能会减少到重复,因为没有其他方法可以轻松地将其适应到类型系统中。如果您能给我们提供更多的信息,我可能会提出更具体的建议。

    作为