Is there an equivalent to the Reader
monad that's equivalent to a -> b -> c
rather than just a -> b
. I know I could do (a, b) -> c
but I'm not sure that's going to be very ergonomic.
Asked
Active
Viewed 240 times
1

joel
- 6,359
- 2
- 30
- 55
-
1[shameless self-promotion](https://hackage.haskell.org/package/effect-stack) – Daniel Wagner Apr 03 '22 at 19:07
-
Just in case someone reading this question is writing an app, in that circumstance I would replace `a` in the reader monad with a problem-specific custom type containing all the relevant things I want access to in the main body of my app. Probably a record type. – AndrewC Apr 09 '22 at 23:54
1 Answers
0
The only way to make that a monad is by wrapping it which may not be what you're after. The instance can be derived
{-# Language DerivingVia #-}
import Control.Monad.Reader
newtype Reader2 a b c = Reader2 (a -> b -> c)
deriving (Functor, Applicative, Monad, MonadFix, MonadReader a)
via ReaderT a ((->) b)
If you derive Representable
it witnesses the isomorphism between Reader2 a b c
and (a, b) -> c
index :: Reader2 a b c -> ((a, b) -> c)
tabulate :: ((a, b) -> c) -> Reader2 a b c

Iceland_jack
- 6,848
- 7
- 37
- 46
-
Why not `newtype ReaderT2 e f m a = ReaderT2 { unReaderT2 :: ReaderT e (ReaderT f m) a }`? – dfeuer Apr 03 '22 at 17:30
-
That works great, and then `type Reader2 a b = ReaderT2 a b Identity` but why do you keep the newtypes inside the definition? And there is a new package [*deriving-trans*](https://hackage.haskell.org/package/deriving-trans) that lets you derive the lifting function for monad transformers: ``MonadTrans via ReaderT e `ComposeT` ReaderT f`` – Iceland_jack Apr 03 '22 at 17:40
-
For `ReaderT`, it probably wouldn't make sense, but for more complicated things you may want to maintain abstraction. – dfeuer Apr 03 '22 at 18:33