
(literate Haskell follows) Hello -cafe, I recently read "Three Layer Haskell Cake" [1] and decided to give it a go. I am stuck on a simple problem and feel like I am missing something easy. One of the first examples is a mocking of an `IO UTCTime` function.
{-# Language FlexibleInstances #-}
data UTCTime = UTCTime Int
class MonadTime m where getCurrentTime :: m UTCTime
instance MonadTime ((->) UTCTime) where getCurrentTime = id
-- instance IO omitted
Everything is clear. I decided to write another function, mocking a stream-of-Char input.
class MonadKeys m where getKeys :: m [Char]
instance MonadKeys ((->) [Char]) where getKeys = id
-- instance IO omitted
Again, fine. But now, if I want to write a function which combines the two external services, like:
someFun :: (MonadTime m, MonadKeys m) => m () someFun = undefined
there is no non-IO instance satisfying the two constraints. I could of course write a type
data Env = Env UTCTime [Char]
and make it instance of MonadTime and MonadKeys, but then I am passing non-relevant arguments to a mocked function like getCurrentTime, which would only need UTCTime. What am I doing incorrectly? -F [1] https://www.parsonsmatt.org/2018/03/22/three_layer_haskell_cake.html