"子类" Haskell中的一个类型

时间:2015-10-15 19:13:41

标签: haskell subclassing

我有一个名为Process的数据类型,它是各种函数的参数。但并非所有流程都相似。有不同类型的Proccesses,它们都有一些共同点,但在其他方面有所不同。我的问题是:我可以用什么成语来模拟这个。

到目前为止我尝试了什么:

第一次尝试

在Process数据类型中的run函数中捕获进程的细节。 run函数的类型对于所有进程都是相同的,但它的实现可能在不同类型的进程之间有所不同。我放弃了这个想法,因为我无法从外部查看run函数,即我无法修改它。我不能改变它的具体方面,我只能提供一个全新的运行功能。 之后10分钟之后的操作将无法实现。

第二次尝试使用多个构造函数

type PlaceDep = Int
type PlaceArr = Int
type DepartureTime = Int
type Speed = Int

data Process = Train      PlaceDep PlaceArr DepartureTime
             | MovingBelt PlaceDep PlaceArr Speed
     deriving (Eq, Show)

prc1 = Train      10 11 1
prc2 = MovingBelt 12 13 2

这让我觉得所有进程都有PlaceDep和PlaceArr的事实似乎有点巧合而且没有明确表达

第3次尝试使用一个构造函数但添加具有多个构造函数的ProcessParameters

type PlaceDep = Int
type PlaceArr = Int

data ProcessParams = DepartureTime Int | Speed Int
                   deriving (Eq, Show)
data Process = Process PlaceDep PlaceArr ProcessParams
                   deriving (Eq, Show)

prc1 = Process   10 11 (DepartureTime 1)
prc2 = Process   12 13 (Speed 2)

到目前为止看起来很有希望。无论如何,我很想知道其他可能的选择。

注意

问题被多次编辑。一些评论和答案可能会引用旧版本。

1 个答案:

答案 0 :(得分:4)

因为,我相信,你知道,Haskell中没有继承。然而,它根本不是问题。像你这样的案例可以通过一种称为“组合”的可扩展方法轻松解决,这种方法最近比OO语言中的“继承”更受欢迎。

你需要做的是在单独的模块中单独实现每个“进程”,然后在另一个模块中有一个围绕类型的圆顶接口,它由所有类型组成。该类型可能是这些特定类型的进程的联合,而其中的函数主要是关于路由到特定实现的函数。 E.g:

module MoreGeneralProcess where

import qualified SpecificProcess1
import qualified SpecificProcess2


data Process = SpecificProcess1 SpecificProcess1.Process |
               SpecificProcess2 SpecificProcess2.Process

doOneGeneralThing :: Process -> IO ()
doOneGeneralThing process =
  case process of
    SpecificProcess1 x -> SpecificProcess1.doOneGeneralThing x
    SpecificProcess2 x -> SpecificProcess2.doOneGeneralThing x

这是一种常见且可无限扩展的模式。 In some Haskell dialects it is even an idiom