scala - Function1 和 Reader Monad 的关系
问题描述
虽然我了解 reader monad 的实现,但我在下面给出了两种最突出的方法:
case class Reader[R, A](run: R => A)
def readerMonad[R] = new Monad[({type f[x] = Reader[R,x]})#f] {
def unit[A](a: => A): Reader[R, A] = Reader(_ => a)
override def flatMap[A,B](st: Reader[R, A])(f: A => Reader[R, B]): Reader[R, B] =
Reader(r => f(st.run(r)).run(r))
}
或更简单地说:
case class Reader[R, A](run: R => A) {
def map[B](f: A => B): Reader[R, B] =
Reader(r => f(run(r)))
def flatMap[B](f: A => Reader[R, B]): Reader[R, B] =
Reader(r => f(run(r)).run(r))
}
我想知道 Reader Monad 和 Function1 之间是否存在内在关系。我一直在准备这里和那里的评论暗示这一点。Reader 根据定义是 Function1 monad 吗?
我不这么认为。但我想围绕这个概念展开思考。
当这些函数的类型为 1 时,对函数进行排序意味着什么?
也就是说,您获取一个函数并应用一个返回相同类型函数的函数。我确实认为 Reader 是一种特定的技术,与函数是函数 1 的事实无关。通过线程化环境只是一种选择,如果我们愿意,可以使用 FunctionN 来完成。
只是一种直觉。
编辑
以下是在 Scala 中进行 FP 编程的练习:
Hard: To cement your understanding of monads,
give a monad instance for the following type,
and explain what it means.
What are its primitive operations?
What is the action of flatMap? ......
case class Reader[R, A](run: R => A)
object Reader {
def readerMonad[R] = new Monad[({type f[x] = Reader[R,x]})#f] {
def unit[A](a: => A): Reader[R,A]
def flatMap[A,B](st: Reader[R,A])(f: A => Reader[R,B]): Reader[R,B]
}
}”
以及让我不满意的部分答案
// The action of Reader's `flatMap` is to pass the `r` argument along to both the
// outer Reader and also to the result of `f`, the inner Reader. Similar to how
// `State` passes along a state, except that in `Reader` the "state" is read-only.
我明白这一点,因为我可以阅读代码。我认为这种解释不足以清楚地回答练习的问题。我正在寻找比代码功能的简单描述更通用的东西。
例如,固定类型 R 意味着什么。这意味着什么链接计算返回作为具有相同输入参数类型的效果函数?
解决方案
Reader[R, A]
是一个包装器R => A
(因此可以在类内部定义方法,而不是作为函数的扩展方法)。一个函数f
可以被包装到一个阅读器Reader(f)
,一个阅读器r
可以被解包到一个函数r.run
。所以Reader[R, A]
↔R => A
是同构。
Reader[R, ?]
有一个类型为 class 的实例Monad
。
R => ?
有一个类型为 class 的实例Monad
。
推荐阅读
- sorting - 使用 Comparable 按表面积对 awt 矩形进行排序
- excel - Excel VBA-具有多个条件的 VLOOKUP
- python - Pandas:在多索引列Dataframe中访问不同顶级列索引下的多个列
- c# - EF核心字符串区分大小写不起作用
- postgresql - 为什么我必须在 PostgreSQL 更新语句的 ELSE 部分使用 CASE 进行类型转换,而不是在 WHEN 部分?
- python - 运行 Python 脚本时使用代理出现问题
- sql-server - Service Broker 中的存储过程无法访问同一服务器实例下的另一个数据库
- c++ - 最新的编译器版本和 GLIBC_2.32 依赖项
- sql - 总结我的数据并添加新属性的最佳方法是什么?
- laravel - 验证取决于单选按钮选择 laravel