简体   繁体   English

如何通过(Int-> Int)使用Reader Monad?

[英]How to use the Reader Monad with (Int -> Int)?

I would like to learn, how to use the Reader Monad. 我想学习如何使用Reader Monad。 Unfortunately only a small amount of example code is available 不幸的是,只有少量的示例代码可用

I would like to create a Reader, where the environment and the retrived values are Int . 我想创建一个Reader,其中的环境和检索的值是Int I defined the type like this: 我定义了这样的类型:

type IntRead = Reader Int Int

The code I tried is this: 我试过的代码是这样的:

addStuff :: Reader Int Int
addStuff = do  
    a <- (*2)  
    b <- (+10)
    return (a+b)  

I get an error, because ReaderT is expected. 我收到一个错误,因为预期使用ReaderT How to create a function like addStuff using the Reader Monad? 如何使用Reader Monad创建类似addStuff的功能? Where should I provide the environment to this function? 我应该在哪里为该功能提供环境?

You can convert functions to readers and back with these two isomorphisms: 您可以将函数转换为读取器,并通过以下两种同构方式返回:

reader :: (r -> a) -> Reader r a
runReader :: Reader r a -> r -> a

Eg 例如

addStuff :: Reader Int Int
addStuff = do  
    a <- reader (*2)  
    b <- reader (+10)
    return (a+b)

and then you can test your code with runReader addStuff 5 . 然后可以使用runReader addStuff 5测试代码。

This is OK for learning purposes. 出于学习目的可以。 For more serious code, you shouldn't use the isomorphisms that much, but instead rely on ask or asks . 对于更严肃的代码,您不应过多地使用同构,而应依赖askasks Eg 例如

addStuff :: Reader Int Int
addStuff = do  
    x <- ask   -- fetch the implicit Int value
    let a = (*2) x
        b = (+10) x
    return (a+b)

or, better 或更好

addStuff :: Reader Int Int
addStuff = do  
    a <- asks (*2) -- fetch the implicit Int value, and apply the function
    b <- asks (+10)
    return (a+b)

or, even better, using applicative style: 甚至更好的是,使用适用风格:

addStuff :: Reader Int Int
addStuff = (+) <$> asks (*2) <*> asks (+10)

The whole point of the reader abstraction is not to think about the underlying function. 读者抽象的全部要点是不考虑底层功能。 You can just pretend to have access to a read-only variable, which is accessible through the ask primitive. 您可以假装可以访问一个只读变量,该变量可以通过ask原语进行访问。

Usually, only at the very last step you use runReader to actually use your monadic reader action. 通常,只有在最后一步,您才使用runReader实际使用单子阅读器操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM