3 votes

Conception du programme concernant les ADT

J'ai un type

data Phase = PhaseOne
           | PhaseTwo
           | PhaseThree deriving Enum

et cinq opérations à effectuer sur chaque phase

  • read
  • write
  • validate
  • evalStatus
  • update

J'ai commencé à essayer de créer une classe de type. Le problème est qu'elles sont toutes du même type. J'aimerais pouvoir faire quelque chose comme

instance MyClass PhaseThree where
  read a = ...

De plus, j'ai besoin de surcharger le type de retour.

Je sais que les cours de type ne sont pas ce que je veux. Mais je ne suis pas sûr de savoir comment faire ce que je veux. J'ai pensé J'ai pensé à un GADT, mais cela ne convient pas tout à fait, car je dois pouvoir placer chaque instance dans un fichier distinct.

J'aimerais avoir des conseils sur les mécanismes que je dois examiner ? Ai-je donné suffisamment d'informations ?

3voto

Daniel Wagner Points 38831

Je recommande d'inverser un peu les choses.

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

phaseOne, phaseTwo, phaseThree :: Phase

(ou un réaménagement similaire des classes en enregistrements explicites).

2voto

jberryman Points 6615

En développant mon commentaire ci-dessus, si vous voulez utiliser trois types différents avec une classe supportant vos opérations, vous pouvez en quelque sorte construire un Enum -avec une fonctionnalité de type succ méthode de classe.

Vous devez également fournir un Done en tant que substitut de 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

Vous pourriez séparer les Succ de la fonctionnalité de votre read , write etc. et créez également deux classes. Les valeurs de retour peuvent être polymorphes.

succ sur votre formulation originale postée est horrible puisque succ PhaseThree ne fait que lancer une erreur. Si vous pouvez faire fonctionner le système de types pour votre application, c'est l'idéal.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X