わかりましたので、パッケージを使用して実装する方法を理解しましたReader
(および、表示されていません):ReaderT
operational
{-# LANGUAGE GADTs, ScopedTypeVariables #-}
import Control.Monad.Operational
data ReaderI r a where
Ask :: ReaderI r r
type Reader r a = Program (ReaderI r) a
ask :: Reader r r
ask = singleton Ask
runReader :: forall r a. Reader r a -> r -> a
runReader = interpretWithMonad evalI
where evalI :: forall b. ReaderI r b -> (r -> b)
evalI Ask = id
しかし、これを無料のモナドで行う方法を一生理解できません (私は Edward Kmett のfree
パッケージを使用しています)。私が得た最も近いものはこれです。これは不正行為であると理解しています((->) r)
(すでにモナドである方法についての何か):
import Control.Monad.Free
type Reader r a = Free ((->) r) a
ask :: Reader r r
ask = Free Pure
runReader :: Reader r a -> r -> a
runReader (Pure a) _ = a
runReader (Free k) r = runReader (k r) r
-- Or, more simply and tellingly:
--
-- > runReader = retract
これが私が思っているほど愚かではなかったとしても、基本的に私が欲しいのはReader
データとして検査できるようにすることなので、それは私が望むものではありません...