为什么所有的仿函数都不能是单子?

时间:2019-10-02 06:41:58

标签: java haskell functional-programming monads vavr

据我所知,函子是具有map()的函子,而Monad是也具有flatMap()的函子。 所有Monad都是函子,但反之则不是。是什么阻止Functors实现flatMap()并成为Monad? 是否存在由于某些限制而保持这种状态的函子。您能否提供一些示例。谢谢。

2 个答案:

答案 0 :(得分:4)

语句所有monad是函子表示仅使用Monad中的方法,我们就可以实现Functor中的方法。确实可以做到这一点,这就是为什么我们说所有单子都是函子。我不知道Vavr,但这是Haskell中执行此操作的一些代码:

{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}

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

相比之下,声明所有函子都是monads 表示,仅使用Functor中的方法,我们就可以实现Monad中的方法。这是无法做到的,因为您可以使用单子函数来完成您无法使用仿函数的事情。所以我们说并不是所有函子都是单子。

答案 1 :(得分:1)

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

“ Functor”是给定类型的非常狭窄的视图。它仅考虑其map()的功能。将其视为“ Functor”的实例时,无需考虑给定类型的任何细节。

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

如果不透明类型不能为我们提供return(),则不能将其视为Monad,

另一个是return(),它不符合Monad法律。

编辑: * 感谢@leftaroundabout指出法律。另一方面,即使绝对不建议在Haskell中声明非法的Monad实例在技术上仍然可行。