本文介绍了有没有任何“标准”利用Reader的等价性和正常功能的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我正在编写一个框架,其中主要功能向用户询问 a - >但是,由于该函数可能非常复杂,因此它的实现通常可能如下所示: fn a = extractPartOfAAndConvert a ++ extractAnotherPartofAAndConvert a 这就是为什么我认为使用 Reader 可能是一个不错的,习惯性的想法。然而,与此同时,我意识到有些人可能不想使用monad。 在尝试时,我制作了这个解决方案: class Iso ab其中 isoFrom :: a - > b isoTo :: b - > a 实例Iso aa其中 isoFrom = id isoTo = id 实例Iso(a - > b)(Reader ab)其中 isoFrom f = reader f isoTo m = runReader m 这反过来又允许我这样做: testCallback :: MyState - >回拨 - > MyState testCallback myState cb = cb myState - 重要签名 testCallbackGeneric :: Iso回调a => MyState - > a - > MyState testCallbackGeneric cb =(isoTo cb)myState callbackFunction :: Callback callbackFunction s = s + 10 callbackMonad :: Reader MyState MyState callbackMonad = do x< - ask return $ x - 10 ----------- 让myStateA = testCallback myState callbackFunction - 让myStateB = testCallback myState callbackMonad - 不起作用,显然 let myStateC = testCallbackGeneric myState callbackFunction let myStateD = testCallbackGeneric myState callbackMonad 然而,我感觉非常像是在重新发明轮子。 有没有一种方法可以表达Reader的等价性,以便轻松编写这样的泛型函数,而不需要创建自己的类型类? ( - >)r 函数已经有一个 MonadReader r 定义在 Control.Monad.Reader 中。您可以使用 MonadReader 约束来编写函数,并将它们作为普通函数或其他 ReaderT monad使用: f :: MonadReader Int m => m int f = do a 返回$ 2 * a + 3 * a 正常:: Int 正常= f 1 - 通常== 5 readerly :: Reader Int Int readerly = do 结果< - f 返回$ 2 *结果 > runReader f 1 5 > runReader readerly 1 10 I am writing a framework, where the main function asks user about the function of type a -> [b].However, because that function can be quite complex, its implementation can often look like this:fn a = extractPartOfAAndConvert a ++ extractAnotherPartofAAndConvert aThat's why I figured using Reader might be a nice, idiomatic idea to fight that. However, at the same time I realize that some people might not want to use a monad.While experimenting, I've crafted this solution:class Iso a b where isoFrom :: a -> b isoTo :: b -> ainstance Iso a a where isoFrom = id isoTo = idinstance Iso (a -> b) (Reader a b) where isoFrom f = reader f isoTo m = runReader mWhich in turn allows me to do:testCallback :: MyState -> Callback -> MyStatetestCallback myState cb = cb myState-- The important signaturetestCallbackGeneric :: Iso Callback a => MyState -> a -> MyStatetestCallbackGeneric myState cb = (isoTo cb) myStatecallbackFunction :: CallbackcallbackFunction s = s + 10callbackMonad :: Reader MyState MyStatecallbackMonad = do x <- ask return $ x - 10-----------let myStateA = testCallback myState callbackFunction-- let myStateB = testCallback myState callbackMonad -- won't work, obviouslylet myStateC = testCallbackGeneric myState callbackFunctionlet myStateD = testCallbackGeneric myState callbackMonadHowever, I feel very much like I'm reinventing the wheel.Is there a way to express the equivalence of Reader to easily write such generic functions without resorting to creating my own type class? 解决方案 You can simply use the fact that the function monad (->) r already has an instance for MonadReader r defined in Control.Monad.Reader. You can write functions using just the MonadReader constraint and use them either as normal functions or in other ReaderT monads:f :: MonadReader Int m => m Intf = do a <- ask return $ 2 * a + 3 * anormally :: Intnormally = f 1-- normally == 5readerly :: Reader Int Intreaderly = do result <- f return $ 2 * result> runReader f 15> runReader readerly 110 这篇关于有没有任何“标准”利用Reader的等价性和正常功能的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 10-30 00:07