Hacker News new | ask | show | jobs
by danidiaz 1155 days ago
> Purifying an (unnecessarily-) IO function into an ordinary function is a good exercise.

Agree! And I would add that you can "purify" a monadic function without having to rewrite it in non-monadic style. You can make it polymorphic over all monads and relegate the "impurity" to monadic functions that you pass as arguments/dependencies. A trivial example:

  twice :: IO ()
  twice = do
      putStrLn "foo"
      putStrLn "foo"
  
  twice' :: forall m. m () -> m ()
  twice' action = do 
      action
      action
This is not that different to having a Spring bean that doesn't perform any effect directly—say, a direct invocation to "Instant.now()"—but instead receives a "Clock" object through dependency injection.

Haskell lets you express the idea of "program logic that only has effects through its dependencies" by being polymorphic over all monads.