从Reader Bool到Maybe的自然变换

13

我正在阅读Bartosz的精彩博客,并在追随第三个挑战问题,但有点困惑:

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。但这感觉有点单子性,或者像嵌套在Reader Bool (Maybe Int)中的Maybe,所以我不确定。

我无法想象如何做到这一点。我能想到最好的方法是:

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

但是这无法考虑环境,也不能返回 Nothing

我想建立一个可交换的结构,通过使用 fmap 和自然变换来构建一个正方形。

例如:

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

你能帮我填补空缺吗?


2
你想让 n 使用环境,但是由于你只有 Reader,没有环境,所以你必须自己提供它。我认为 Just (f True)Just (f False)Nothing 都是这些函子之间的自然变换。 - lisyarus
1个回答

19

正如我在评论中已经说过的,你想要n使用环境,但是由于你只有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引理告诉我们:

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,它们对应于答案开头的实现。


有道理!那么在 Reader BoolMaybe 之间只有 3 种可能的自然变换,对吗?然后在问题#2中,他要求从 Reader()List 的自然变换。我想到的是:n(Reader f)=[f()]和无限的n(Reader f)= [()...()]。这准确吗? - Josh.F
1
@Josh.F,Reader() 在道德上等同于 Identity。因此,您需要获取一个元素并将其转换为列表。因此,每个自然数(不要忘记0)都有一个这样的自然变换,加上无限大的自然变换。我想是这样的。 - dfeuer
2
@dfeuer 没错!Yoneda也给出了相同的结论:自然变换 Reader() -> List 对应于 List(). - lisyarus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接