4 ms·
Yes, and for interested parties it's probably worth elaborating that Git might be something like class Git m where clone :: Url -> m GitRepo
by tome 2y ago
Yes, and for interested parties it's probably worth elaborating that Git might be something like
class Git m where
clone :: Url -> m GitRepo
currentHead :: GitRepo -> m CommitHash
and Logging might be something like
class Logging m where
log :: String -> m ()
which is very similar to defining
data GitDict m = MkGitDict {
clone :: Url -> m GitRepo,
currentHead :: GitRepo -> m CommitHash
}
data LoggingDict m = MkLoggingDict {
log :: String -> m ()
}
class Git m where gitDict :: GitDict m
class Logging m where loggingDict :: LoggingDict m
So the "record of functions" style and the "final tagless" style are equivalent, except that the former passes operations manually and the latter passes operations implicitly. The former can be considered more cumbersome, but is more flexible.
If you're interested in how my effect system Bluefin does this, you can have a look at https://hackage.haskell.org/package/bluefin-0.0.4.2/docs/Bluefin-Compound.html https://hackage.haskell.org/package/bluefin-0.0.4.2/docs/Blu...