【问题标题】:Why does the Reader monad store a function?为什么 Reader monad 存储一个函数?
【发布时间】:2015-12-31 12:58:09
【问题描述】:

根据 All about monads

(Reader monad 的)Monad 值是从环境到值的函数。界 函数应用于绑定值,并且两者都可以访问 共享环境。

但是,为什么必须在这个 monad 中使用一个函数(而不是,例如,两个变量,一个用于环境,一个用于值)?

【问题讨论】:

    标签: haskell monads


    【解决方案1】:

    一个更数学的论点:

    考虑当您修改环境时会发生什么。例如,假设您有一个包含Int 的环境,但您的Reader 需要Integer。也就是说,你有

    yourReader :: Reader Integer A
    

    好吧,显然你可以在环境中转换Int,只需使用

    fromIntegral :: Int -> Integer
    

    但这对你的 reader monad 意味着 convertReader Int A,因为只有这种类型在你的原始环境中有效。

    yourReader' :: Reader Int A
    yourReader' = withReader fromIntegral yourReader
    

    数学家通过在第一个参数中说Readercontravariant 来描述这一点。但是,如果它只包含一个用于值的变量和一个用于环境的变量,那么它在两个参数中都是co变体(即Int -> Integer 会将Reader Int A 转换为Reader Integer A,而不是其他方式)。而函数类型在其左侧是逆变的。

    【讨论】:

      【解决方案2】:

      reader monad 的重点是对一个依赖 环境的值进行建模。或者,如果您愿意,可以使用“隐式”输入进行计算。这不同于在其环境中存储的值。

      考虑一下:

      newtype Reader s a = Reader (s -> a)
      
      ask :: Reader a a
      ask = Reader (\s -> s)
      

      这里的价值和环境是一样的。以上只是简单地从环境中“获取”值并返回它。

      相比之下,

      newtype Reader s a = Reader (s, a)
      
      ask :: Reader a a
      ask = Reader (s, s)
         where s = ???
      

      在这里,我们需要同时产生环境和价值。但是我们没有实际的方法来做到这一点!环境从第一个示例中的输入转变为输出——这使得实现ask 成为不可能。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-02-16
        • 1970-01-01
        • 2017-07-04
        • 2018-03-26
        • 1970-01-01
        • 1970-01-01
        • 2014-05-07
        • 1970-01-01
        相关资源
        最近更新 更多