【问题标题】:Why can't all Functors be Monads? [duplicate]为什么不能所有的 Functor 都是 Monad? [复制]
【发布时间】:2020-01-31 10:18:20
【问题描述】:

据我所知,函子是那些有map() 的,而单子是那些也有flatMap() 的。 所有的 Monad 都是 Functor,但反之则不然。是什么阻止了 Functor 实现 flatMap() 并成为 Monad? 由于某些限制,是否有任何函子保持这种状态。你能提供一些例子吗?谢谢。

【问题讨论】:

标签: java haskell functional-programming monads vavr


【解决方案1】:

all monads are functors 的意思是,只使用 Monad 的方法,我们就可以实现 Functor 的方法。这确实可以做到,这就是为什么我们说所有的单子都是函子。我不知道 Vavr,但这是 Haskell 中的一些代码:

{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}

instance Monad m => Functor m where
    fmap f x = x >>= (\x' -> return (f x'))

相比之下,all functors are monads这句话意味着,仅使用 Functor 中的方法,我们就可以实现 Monad 中的方法。这是做不到的,因为你可以用 monad 做一些你不能用 functor 做的事情。所以我们说并不是所有的函子都是单子。

【讨论】:

  • 这是伪 Haskell 吗?我无法声明 Functor 实例:“Functor m 的非法实例声明”。 repl.it/repls/TiredThunderousMigration
  • @MichaWiedenmann {-# LANGUAGE FlexibleInstances, UndecidableInstances #-} 是这种实例声明所必需的。这些是非常常见的语言扩展,您实际上会在(我估计)所有 Haskell 源文件的一半上找到它们。 (但即使有这些扩展,如果你编写那个实例,它当然会出错,因为它与直接声明的 Functor 实例冲突。)
  • @leftaroundabout 感谢您的编辑!看起来你最近一直在纠正我的许多其他答案,所以也谢谢你的那些!
  • @MichaWiedenmann 我确实打算让它有点“伪 Haskell”。您实际上不能定义这样的实例,因为它与具有已定义 Monad 实例的类型的许多其他 Functor 实例冲突,但它表明这样的实例 可以 以类型检查和 (排序)的作品。一个更好的例子是定义一个新函数monad_fmap :: Monad m => (a -> b) -> m a -> m b,并实现它而不是fmap
  • @bradrn monad_fmap 又名liftM。 :)
【解决方案2】:

如果一个类型实现了flatMap()(以及return()/unit()/emit()/inject()/wrap()/...),根据定义,它已经是一个Monad。

“函子”是给定类型的非常狭窄的视图。它只考虑其map() 的能力。当将其视为“函子”的实例时,不考虑给定类型的任何细节。

如果给定类型可以实现守法(*)flatMap()(以及return()),那么它也可以被视为“Monad”的合法实例。

如果一个 opaque 类型没有为我们提供return(),它就不能被视为 Monad,这是一种可能性。

另一个是flatMap(),它不遵循单子定律。

edit: (*) 感谢@leftaroundabout 指出法律。另一方面,在 Haskell 中声明一个非法的 Monad 实例在技术上仍然是可行的,尽管这肯定是不可取的。

【讨论】:

    猜你喜欢
    • 2017-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-25
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    • 2011-04-30
    相关资源
    最近更新 更多