Unit testing IO in Haskell
blog.pusher.com
Unit testing IO in Haskell
1–10 of 11 posts
Re: Unit testing IO in Haskell
#2Re: Unit testing IO in Haskell
#3Re: Unit testing IO in Haskell
#4I still find myself preferring to use a dependency injection style when writing Haskell. The code ends up looking similar, and more flexible, in my opinion (you can inject different dependencies based on runtime values).
Here is an example using the method described in the article vs. dependency injection to print out the current time.
Article:
class MonadTime m where
getTime :: m Integer
class MonadPrint m a where
doPrint :: a -> m ()
instance MonadTime IO where
getTime = do
TOD s _ MonadPrint IO a where
doPrint = print
printTime :: (Monad m, MonadPrint m Integer, MonadTime m) => m ()
printTime = getTime >>= doPrint
main :: IO ()
main = printTime
Dependency injected: data MonadPrint m a = MonadPrint { doPrint :: a -> m () }
data MonadTime m = MonadTime { getTime :: m Integer }
ioMonadTime :: IO Integer
ioMonadTime = do
TOD s _ MonadPrint m Integer -> MonadTime m -> m ()
printTime MonadPrint{..} MonadTime{..} = getTime >>= doPrint
main :: IO ()
main = printTime (MonadPrint print) (MonadTime ioMonadTime)
Good read on the subject of being careful with overusing typeclasses:http://www.haskellforall.com/2012/05/scrap-your-type-classes...
Re: Unit testing IO in Haskell
#5This is a good post in that it illustrates how it's possible to write useful Haskell that interacts with the real world without weaving IO through the entire codebase (as many beginners end up doing). I still find myself preferring to use a dependency injection style when writing Haskell. The code ends up looking similar, and more flexible, in my opinion (you can inject different dependencies based on runtime values)…
Re: Unit testing IO in Haskell
#6finally someone did haskell examples in decent modern blog UI instead of old fashioned dark depressing terminal-like colors ;)
Re: Unit testing IO in Haskell
#7This is a good post in that it illustrates how it's possible to write useful Haskell that interacts with the real world without weaving IO through the entire codebase (as many beginners end up doing). I still find myself preferring to use a dependency injection style when writing Haskell. The code ends up looking similar, and more flexible, in my opinion (you can inject different dependencies based on runtime values)…
Of course typeclasses can be viewed as dependency injection as well. It its just that with typeclasses the injection is implicit rather than explicit. But mechanically they are identical
Re: Unit testing IO in Haskell
#8Earlier quoted context omitted.
Of course typeclasses can be viewed as dependency injection as well. It its just that with typeclasses the injection is implicit rather than explicit. But mechanically they are identical
The main difference is that typeclasses are injected at compile time rather than run time. By being explicit, I can inject different behavior based on runtime values.
Re: Unit testing IO in Haskell
#9Earlier quoted context omitted.
The main difference is that typeclasses are injected at compile time rather than run time. By being explicit, I can inject different behavior based on runtime values.
well, the typeclasses are 'determined' at compile-time, but they are certainly de-sugared into extra function paramaters that are still passed around (injected) at run-time. Haskell does not completely specialize this away (even though in theory it could). But i grant you manual threading allows the user to do different things than expected.
Re: Unit testing IO in Haskell
#10This is a good post in that it illustrates how it's possible to write useful Haskell that interacts with the real world without weaving IO through the entire codebase (as many beginners end up doing). I still find myself preferring to use a dependency injection style when writing Haskell. The code ends up looking similar, and more flexible, in my opinion (you can inject different dependencies based on runtime values)…
Of course typeclasses can be viewed as dependency injection as well. It its just that with typeclasses the injection is implicit rather than explicit. But mechanically they are identical
I reckon I will need to re-implement my mocks using the technique you describe to really understand the motivation.