我正在阅读Haskell/Category理论,以下是该文章中monad的定义:
monad是一种特殊类型的仿函数,从类别到同一类别,支持一些额外的结构.所以,归结为定义.monad是一个仿函数M:C-> C,以及C中每个对象X的两个态射:
单位:X - > M(X)
连接:M(M(X)) - > M(X)
据我所知,在Haskell return
中相当于unit
.但return
我可以写:
x :: [Int] -- x is a member of Lst category x = return 5
这是Haskell中的有效代码.现在,正如你所看到的,5
这里不是一个成员Lst
,而是return
为它工作.
所以,我想这Lst
是不是С从L:C->Ç.但是谁呢?
也许正确的答案是Hask
,但我不确定" 从类别到其子类别的仿函数 "与" 从类别到同一类别的仿函数"相同.
这是一个常见的混淆点,你已经清楚地问了这个问题,以便它可以回答.
我不确定" 从类别到它的子类别的仿函数 "与" 从类别到同一类别的仿函数"相同.
这是不一样的.仿函数由四个数据组成:源类别C,目标类别D,C对象到D对象的映射,以及C的态射映射到D的态射,满足某些条件.如果更改D,则更改仿函数.
然而,当我们定义一个仿函数时,我们经常在类别D中有一些选择.我从你的问题推断出这Lst
是一个子类,Hask
其对象是形式的类型[a]
,尽管我不确定Lst
应该是什么样的态射.我们可以定义[]
这两种形状之一的仿函数:
[]
:Hask
- > Lst
(即目标类别[]
是Lst
)
[]
:Hask
- > Hask
(即目标类别[]
是Hask
)
这些是技术上不同的仿函数,我们必须做出选择.在这种情况下,正确的选择是选择2.我们需要的源和目标的类别是一样的,因为我们需要应用[]
到的输出[]
中join
.所以C = Hask
和M = []
.
一般来说,考虑类似的类Lst
被定义为某种类型构造函数的图像,很少有用.我不确定这个(非常常见的)想法来自哪里.我建议你抛开"类别Lst
" 的想法.现在只有一个类别就足够了!
对于类比,考虑对实数f(x)= x ^ 2求平方的函数.我们可以将其视为函数f:R - > R从实数到实数,即使碰巧f(x)只取非负实数.f的目标不必等于f的图像(f对其输入值实际获得的值).