自由单子总是存在吗?

n. *_* m. 38 haskell category-theory free-monad

我们从类别理论中知道,并非Set中的所有endofunctors都承认一个免费的monad.规范的反例是powerset仿函数.

但是Haskell可以将任何仿函数变成一个免费的monad.

data Free f a = Pure a | Free (f (Free f a))
instance Functor f => Monad (Free f) where
  return = Pure
  Pure a >>= f = f a
  Free m >>= f = Free ((>>= f) <$> m)
Run Code Online (Sandbox Code Playgroud)

是什么让这个构造适用于任何Haskell仿函数但在Set中分解?

dfe*_*uer 4

很明显这个答案是错误的。我将其留在这里是为了在评论中保留有价值的讨论,直到有人提出正确的答案。


考虑 中设置的幂Set。如果我们有一个函数f : S -> T,我们可以f' : PS S -> PS T通过 来形成f' X = f [X]。很好的协变函子(我认为)。我们还可以组成f'' X = f^(-1) [X],一个很好的逆变函子(我认为)。

让我们看看Haskell中的“幂集”:

newtype PS t = PS (t -> Bool)
Run Code Online (Sandbox Code Playgroud)

这不是一个Functor而只是一个Contravariant

instance Contravariant PS where
  contramap f (PS g) = PS (g . f)
Run Code Online (Sandbox Code Playgroud)

我们认识到这一点是因为t处于消极位置。与 不同的是Set,我们无法获得构成幂集的特征函数的“元素”,因此协变函子不可用。

因此,我推测 Haskell 承认每个协变函子都有一个自由单子的原因是它排除了那些给 带来麻烦的协变函子Set

  • 协变幂集函子无法在 Haskell 中表达,但同样麻烦的“双幂集函子”`(a -&gt; Bool) -&gt; Bool` 可以。所以,这不相关。 (5认同)
  • 请记住,“(-&gt;)”在 Haskell 中表示“可计算”函数,因此“a -&gt; Bool”不是“a”的幂集,而是“a”的可计算幂集,后者更小。这使我们能够形成集合理论上不可能的类型,例如“newtype S = S (S -&gt; Bool)” (4认同)
  • @nm 两个简单的元素:“empty = S (const False)”和“full = S (const True)”。更复杂的是“containingEmpty = S (\(S f) -&gt; fempty)”。等等,至于你如何用它来回答你的问题,我不确定,我只是觉得它是相关的。 (2认同)