Hacker News new | ask | show | jobs
by tome 638 days 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/Blu...