Ok, vì vậy tôi đã tìm ra cách để thực hiện Reader
(và ReaderT
, không hiển thị) bằng cách sử dụng operational
gói:Làm cách nào để triển khai Reader bằng monads miễn phí?
{-# 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
Nhưng tôi không thể tìm ra cho cuộc sống của tôi làm thế nào để làm điều này với monads miễn phí (Tôi đang sử dụng gói free
của Edward Kmett). Gần nhất tôi đã nhận được là thế này, mà tôi hiểu được gian lận (một cái gì đó về cách ((->) r)
đã là một đơn nguyên):
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
Thậm chí nếu điều này không phải như câm như tôi nghi ngờ nó là, nó không phải là những gì tôi muốn vì điều tôi muốn, về cơ bản, là có thể kiểm tra số Reader
làm dữ liệu ...
Tôi không nghĩ rằng nó có thể được thực hiện mà không có một loại chức năng ở đâu đó. –