我有一个名为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)
到目前为止看起来很有希望。无论如何,我很想知道其他可能的选择。
注意
问题被多次编辑。一些评论和答案可能会引用旧版本。
答案 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