{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE InstanceSigs #-} {-# LANGUAGE FlexibleContexts #-}
module Lib ( someFunc ) where
import Control.Monad (liftM, ap)
-- Step 1: 定义 ReaderT 类型 newtypeReaderT r m a = ReaderT { runReaderT :: r -> ma }
-- Step 2: 实现 Functor 实例 instanceFunctor m => Functor (ReaderTrm) where fmap f (ReaderT r) = ReaderT $ \env -> fmap f (r env)
-- Step 3: 实现 Applicative 实例 instanceMonad m => Applicative (ReaderTrm) where pure x = ReaderT $ \_ -> pure x (ReaderT f) <*> (ReaderT x) = ReaderT $ \env -> do func <- f env val <- x env return (func val)
-- Step 4: 实现 Monad 实例 instanceMonad m => Monad (ReaderTrm) where return x = ReaderT $ \_ -> return x (ReaderT r) >>= k = ReaderT $ \env -> do a <- r env letReaderT r' = k a r' env
-- Step 5: 实现 MonadReader 类 classMonad m => MonadReader r m | m -> r where ask :: m r local :: (r -> r) -> m a -> m a
-- Step 6: 实现 ReaderT 的 MonadReader 实例 instanceMonad m => MonadReader r (ReaderTrm) where ask = ReaderT return local f (ReaderT r) = ReaderT $ \env -> r (f env)
-- Step 7: 定义 someFunc 测试函数 testReaderT :: IO () testReaderT = do let reader = ReaderT $ \env -> return ("Environment: " ++ env) result <- runReaderT reader "TestEnv" putStrLn result let askReader = ask :: ReaderTStringIOString env <- runReaderT askReader "TestEnv" putStrLn ("ask: " ++ env) let localReader = local (\env -> env ++ " Modified") askReader modifiedEnv <- runReaderT localReader "TestEnv" putStrLn ("local: " ++ modifiedEnv)
-- 修改后的 testMonadReader 函数,启用 FlexibleContexts testMonadReader :: (MonadReaderString m) => m String testMonadReader = do env <- ask -- 获取环境变量,这里 r 被具体化为 String let modifiedEnv = env ++ " Modified" return modifiedEnv
someFunc :: IO () someFunc = do -- 运行 ReaderT 测试 testReaderT -- 运行使用 MonadReader 约束的测试 let result = testMonadReader :: ReaderTStringIOString modifiedEnv <- runReaderT result "TestEnv" putStrLn ("testMonadReader: " ++ modifiedEnv)