In effect systems like effectful or fused-effects, effects are defined as sum types:
data FileSystem :: Effect where
ReadFile :: FilePath -> FileSystem m String
WriteFile :: FilePath -> String -> FileSystem m ()
And there’s a typeclass like :>
or Member
that says “this effect is part of the whole set of effects”.
Meanwhile, when using the so-called “ReaderT pattern” (a.k.a. “handle pattern”), components are records-of-functions like
data FileSystem = FileSystem {
readFile :: FilePath -> m String
writeFile :: FilePath -> String -> m ()
}
And (in some formulations) there’s a typeclass like Has
that says “this component is part of the whole set of components”.
I personally prefer the records-of-functions + Has
approach because it’s easier to reuse intuitions coming from object-oriented programming.
What are the benefits of the sum-of-constructors + Member
approach?