3

我有一个类型

data Phase = PhaseOne
           | PhaseTwo
           | PhaseThree deriving Enum

以及每个阶段要做的五项操作

  • read
  • write
  • validate
  • evalStatus
  • update

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

instance MyClass PhaseThree where
  read a = ...

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

我知道类型类不是我想要的。但我不确定如何做我想做的事。我想到了一个 GADT,但这并不完全正确,因为我需要能够将每个实例放在一个单独的文件中。

我想要一些关于我需要调查哪些机制的建议?我是否提供了足够的信息?

4

2 回答 2

3

我建议稍微颠倒一下。

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

phaseOne, phaseTwo, phaseThree :: Phase

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

于 2012-07-03T02:46:46.123 回答
2

详细说明我上面的评论,如果您想在一个支持您的操作的类中使用三种不同的类型,您可以Enum使用类方法构建类似 - 的功能succ

您还必须提供一个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功能与您的read,write等方法分开并创建两个类。返回值可以是多态的。

succ在您最初发布的公式上是可怕的,因为succ PhaseThree只会引发错误。如果您可以让类型系统适用于您的应用程序,那将是理想的选择。

于 2012-07-03T18:16:00.250 回答