Kleisli、ReaderT 和 Reader 在 Scalaz 中相同只是巧合吗
Is it just a coincidence that Kleisli, ReaderT, and Reader are the same in Scalaz
在 Scalaz 中
Kleisli[F, A, B]
是 A => F[B]
的包装器。
ReaderT[F, A, B]
-- reader monad transformer -- 只是 Kleisli[F, A, B]
的别名。
Reader[A, B]
monad 是 ReaderT
的特化,身份为 monad Id
:
type Reader[A, B] = ReaderT[Id, A, B]
。
Kleisli
、ReaderT
和 Reader
在 Scalaz 中是同构的,这只是巧合还是有一些更深层的原因?
你可以把它想象成通过两条不同的路线到达同一个地方。一方面,您从 reader monad 开始,它只是一种函数包装器。然后你意识到你想将这个 reader 功能与其他 "effects" 集成到一个更大的 monad 中,所以你创建了一个 ReaderT
monad 转换器。在这一点上,将您的原始 Reader[E, ?]
实现为 ReaderT[Id, E, ?]
.
是有意义的
另一方面,您需要一个类型来表示 Kleisli 箭头(即具有单子 return 类型的函数)。事实证明,这与 ReaderT
是同一回事,因此您只需将其作为别名即可。
"it turns out" 部分没有什么特别神秘的地方。这有点像如果你开始使用 Addable
类型 class 来处理类似数字的东西,然后决定让它更通用,最终得到一个 class 类型,它只提供关联 "addition-like" 操作。您重新发明了 Semigroup
!不过,出于历史或教学原因,或者只是为了方便起见,您可能仍希望保留 Addable
名称。
这就是 Reader
和 ReaderT
的所有情况——您 不需要 这些别名,但它们很方便,并且可能有助于改进代码的清晰度。
在 Scalaz 中
Kleisli[F, A, B]
是A => F[B]
的包装器。ReaderT[F, A, B]
-- reader monad transformer -- 只是Kleisli[F, A, B]
的别名。Reader[A, B]
monad 是ReaderT
的特化,身份为 monadId
:
type Reader[A, B] = ReaderT[Id, A, B]
。
Kleisli
、ReaderT
和 Reader
在 Scalaz 中是同构的,这只是巧合还是有一些更深层的原因?
你可以把它想象成通过两条不同的路线到达同一个地方。一方面,您从 reader monad 开始,它只是一种函数包装器。然后你意识到你想将这个 reader 功能与其他 "effects" 集成到一个更大的 monad 中,所以你创建了一个 ReaderT
monad 转换器。在这一点上,将您的原始 Reader[E, ?]
实现为 ReaderT[Id, E, ?]
.
另一方面,您需要一个类型来表示 Kleisli 箭头(即具有单子 return 类型的函数)。事实证明,这与 ReaderT
是同一回事,因此您只需将其作为别名即可。
"it turns out" 部分没有什么特别神秘的地方。这有点像如果你开始使用 Addable
类型 class 来处理类似数字的东西,然后决定让它更通用,最终得到一个 class 类型,它只提供关联 "addition-like" 操作。您重新发明了 Semigroup
!不过,出于历史或教学原因,或者只是为了方便起见,您可能仍希望保留 Addable
名称。
这就是 Reader
和 ReaderT
的所有情况——您 不需要 这些别名,但它们很方便,并且可能有助于改进代码的清晰度。