Hi all,

I have a bunch of data types which are "divided" in other data types as following:
type FileName   = String

data FileWish   = File FileName
                deriving (Show, Eq)


data FileFact   = FileExist
                | FileDontExist
                deriving (Show, Eq)


data FileAction = FileCreate
                deriving (Show, Eq)

observe :: FileWish -> [FileFact]
observe :: undefined

plan :: FileWish -> FileFact -> [FileAction]
plan (File _) FileDontExist = [FileCreate]
plan (File _) FileExist = []


perform :: FileWish -> [FileAction] -> IO ()
perform :: undefined


I want to have a model as extensible as possible, even if I'm new to Haskell, I think that it's preferable to base parts of system on behavior (type classes) rather than data types.

So I have File that give a Wish, a Fact (via observe) and a Action (via plan).
I want to put observe, plan and perform in different type classes (let's say Observable, Plannable and Performable).

When I create a new thing (like File) I want, for example, that :
observe :: Wish e -> [Fact e]

where e is File.
But I want (Fact e) be an instance of Plannable.
And so on.

At first glance, I think I have to use this: https://www.fpcomplete.com/school/to-infinity-and-beyond/pick-of-the-week/type-families-and-pokemon
But it is coupled to data type and one type class.

If you have any hints for me.
Maybe I don't take the right way to solve my problem.

Thanks in advance.