从 Reader Bool 到 Maybe 的自然转换

Natural Transformations From Reader Bool To Maybe

我正在阅读 Bartosz 的精彩博客,并继续回答挑战问题 3,我有点难过:

https://bartoszmilewski.com/2015/04/07/natural-transformations/

Q3:定义一些从Reader BoolMaybe

的自然变换

我将 Reader 仿函数定义为:

newtype Reader e a = Reader (e->a)

runReader :: Reader e a -> e -> a
runReader (Reader f) env = f env

instance Functor (Reader e) where
    fmap f (Reader g) = Reader (\x -> f (g x))

而且我想找到一个自然的变换

n :: Reader Bool a -> Maybe a

我的直觉是,如果 Reader 的环境是 True,我可以有一个 Just a,如果 False,那么自然变换投射到 Nothing。但这感觉有点单调,或者像 Maybe 嵌套在 Reader 中,就像 Reader Bool (Maybe Int),所以我不确定。

我不知道该怎么做。我拥有的最好的是:

n :: Reader Bool a -> Maybe a
n (Reader f) = Just (f True)

但这不能考虑环境,也不能returnNothing.

我想构建一个通勤结构,用 fmap 和自然变换构建一个正方形。

例如:

                          nat
Reader Bool Int +---------------------------> Maybe Int
     +                                            +
     |                                            |
     |                                            |
     |                                            |
     |    fmap show                               |  fmap show
     |                                            |
     |                                            |
     |                                            |
     |                                            |
     v                  nat                       v
Reader Bool String  +--------------------------> Maybe String                         

你能帮我填补空白吗?

正如我在评论中已经说过的,你想要使用环境,但是,由于你只有Reader,所以没有环境,你必须自己提供。

显然,这实际上是三个不同自然变换Reader Bool a -> Maybe a:

n (Reader f) = Just (f True)

n (Reader f) = Just (f False)

n (Reader f) = Nothing

让我们证明没有更多。在范畴论术语中,函子 Reader Bool a 就是 Hom(Bool,_)。现在,Yoneda lemma 告诉我们

Nat(Hom(X,_), F) = F(X)

也就是说,从函子Hom(X,_)到函子F的自然变换与集合F(X)的元素一一对应。

在我们的例子中,X = BoolF = Maybe,所以我们得到

Nat(Hom(Bool,_),Maybe) = Maybe Bool

Maybe Bool正好包含三个元素:Just TrueJust FalseNothing,对应答案开头的实现。