关于ADT的程序设计

时间:2012-07-02 22:36:14

标签: haskell

我有一个类型

data Phase = PhaseOne
           | PhaseTwo
           | PhaseThree deriving Enum

和每个阶段要做的五项操作

  • read
  • write
  • validate
  • evalStatus
  • update

我开始尝试创建一个类型类。问题是,它们都是同一类型。 我希望能够做一些像

这样的事情
instance MyClass PhaseThree where
  read a = ...

另外,我需要重载返回类型。

我知道类型类不是我想要的。但我不知道该怎么做我想要的。我想 一个GADT,但这不太正确,因为我需要能够将每个实例放在一个单独的文件中。

我想了解一下我需要调查哪些机制?我有足够的信息吗?

2 个答案:

答案 0 :(得分:3)

我建议稍微改变一下。

data Phase = Phase {
    read :: String -> Foo,
    write :: Foo -> IO (),
    validate :: Foo -> Bool,
    evalStatus :: IO (),
    update :: Foo -> Foo
}

phaseOne, phaseTwo, phaseThree :: Phase

(或类似的将类重新调整为显式记录)。

答案 1 :(得分:2)

在上面的评论中,如果你想在支持你的操作的类中使用三种不同的类型,你可以使用Enum类方法构建succ类功能。 / p>

您还必须提供Done类型作为succ PhaseThree

的占位符
{-# LANGUAGE MultiParamTypeClasses , FunctionalDependencies #-}
data PhaseOne = PhaseOne
data PhaseTwo = PhaseTwo
data PhaseThree = PhaseThree

data Done = Done

class YourClass p0 p1 | p0 -> p1 where
    succ :: p0 -> p1
    -- read :: ...
    -- write :: ...etc

instance YourClass PhaseOne PhaseTwo where
    succ PhaseOne = PhaseTwo
    -- read = ...

instance YourClass PhaseTwo PhaseThree where
    succ PhaseTwo = PhaseThree

instance YourClass PhaseThree Done where
    succ PhaseThree = Done

您可以将Succ功能与readwrite等方法分开,并创建两个类。返回值可以是多态的。

原始发布的公式上的

succ非常糟糕,因为succ PhaseThree只会引发错误。如果您可以使类型系统适用于您的应用程序,那就是理想的选择。