单声道不具有“ flatMap”而是具有“ flatUnit”?

时间:2018-10-24 15:57:19

标签: javascript haskell functional-programming monads category-theory

范畴论中的单子词由三元组 T,单位,平坦⟩定义。

class Monad t where
  map :: (a -> b) -> (t a -> t b) -- functorial action
  unit :: a -> t a
  flat :: t (t a) -> t a

class KleisliTriple t where
  unit :: a -> t a
  flatMap :: t a -> (a -> t b) -> t b

KleisliTriple通过由flatMapbind组成的map(或Haskell中的flat)运算符来对结构进行平整。

但是,我一直认为,理解和实现函数式编程中的Monad概念以使对象{例如flatUnitunit flat

在这种情况下,flatUnit(flatUnit(x)) = flatUnit(x)。我实际上是在JavaScript中以这种方式实现的,并且使用flatUnitmap(只是一个传统的函子运算符),似乎可以得到Monad的所有好处。

所以,这是我的问题。

我一直在寻找有关函数编程中flatUnit形式化的文档,但从未找到。我了解有一个历史背景,Eugenio Moggi首先发现了函数式编程中monad的相关性,并且在他的论文中碰巧是KleisliTriple应用程序,但是由于Monad不限于Kleisli类别并且考虑了flatUnit的简单性,对我来说很奇怪。

那是为什么?我想念什么?

编辑:代码已删除。

1 个答案:

答案 0 :(得分:10)

在这个答案中,我不会停留在flatUnit上。正如其他人指出的那样,join . return = id适用于任何monad(这是monad法则之一),因此就其本身而言,没有太多要讨论的内容。相反,我将讨论此处讨论中提出的一些周围主题。

引用评论:

  

换句话说,具有扁平结构的函子是单子。

我认为,这是问题的核心。 monad不必是具有平坦结构的函子,而可以是其值可以按照某些定律(“类别中的类齐半体”)被 tened (带有join)的函子。俗话说)。平整化不需要是无损操作(即join是同构)。

join是同构的Monad,在范畴论中被称为idempotent monads 1 。但是,要使Haskell Monad成为幂等,单价值必须没有额外的结构。这意味着程序员最关注的大多数monad并不是幂等的(实际上,我很难想到不是Monad或类似身份的幂等的Haskell Identity)。评论中已经提出的一个示例是列表:

join [[1,2],[3,4,5]] = [1,2,3,4,5] -- Grouping information discarded

函数/阅读器monad给出了一个更加生动的插图:

join (+) = \x -> x + x

This recent question提供了涉及Maybe的有趣插图。那里的OP具有签名功能...

appFunc :: Integer -> Integer -> Bool -> Maybe (Integer,Integer)

...并像这样使用它...

appFunc <$> u <*> v <*> w

...从而获得Maybe (Maybe (Integer, Integer))的结果。 Maybe的两层分别对应两种不同的失败方式:如果uvwNothing,我们得到Nothing;如果失败,则失败。如果其中三个是Just值,但appFunc的结果是Nothing,则得到Just Nothing;最后,如果一切成功,我们将在Just中获得一个Just值。现在,可能像我们这个问题的作者一样,我们并不在意Maybe的哪一层导致了失败。在这种情况下,我们可以通过在结果上使用join或将其重写为u >>= \x -> v >>= \y -> w >>= \b -> appFunc x y b来丢弃该信息。无论如何,这些信息都可以供我们使用或丢弃。


注1:在King和Wadler(Wadler's papers about monads之一)的 Combining Monads 中,作者引入了一个不同的,且几乎无关的含义,即“幂等单子”。从他们的意义上讲,一个幂等单子是f <$> u <*> u = (\x -> f x x) <$> u的一个例子(适用的表示法)是Maybe