好的,关于 Monad ,我知道有足够的问题被问到了。我并不想打扰任何人再次询问什么是monad 。
实际上,我读过What is a monad?,这非常有帮助。我觉得我非常接近真正理解它。
我在这里创建这个问题只是为了描述我对Monad和Function的一些看法,并希望有人能够纠正我或确认它是正确的。
该帖子中的一些答案让我觉得 monad 有点像 function 。
Monad接受一个类型,返回一个包装类型(return
),它也可以采用一种类型,对它进行一些操作并返回一个包装类型(bind
)。
从我的角度来看,它有点像 function 。一个函数需要一些东西并做一些操作并返回一些东西。
那么为什么我们甚至需要monad ?我认为其中一个关键原因是monad为初始数据/类型的顺序操作提供了更好的方法或模式。
例如,我们有一个初始整数i
。在我们的代码中,我们需要逐步应用10个函数f1, f2, f3, f4, ..., f10
,即我们首先在f1
上应用i
,获取结果,然后对其应用f2
结果,然后我们得到一个新结果,然后应用f3
...
我们可以通过函数原始执行此操作,就像f1 i |> f2 |> f3...
一样。但是,步骤中的中间结果不一致;此外,如果我们必须在中间的某个地方处理可能的失败,事情会变得很难看。如果我们不希望整个过程在异常上失败,那么无论如何都必须构造Option
。很自然地,monad
进来了。
Monad统一并强制所有步骤中的返回类型。这大大简化了代码的逻辑和可读性(这也是design patterns
的目的,不是这样)。此外,它更容易防止错误或错误。例如,Option Monad
强制每个中间结果为options
,并且很容易实现fast fail
范例。
就像monad描述的很多帖子一样,monad是一种设计模式,是一种更好的方法,可以将功能/步骤结合起来构建流程。
我理解正确吗?
答案 0 :(得分:1)
听起来像你通过类比发现了学习的极限。 Monad被精确地定义为Haskell中的类型类和类别理论中的代数类;任何比较使用" ...喜欢......"将是不精确的,因此是错误的。
所以不,因为Haskell的monad不像函数,因为它们1)实现为类型类,2)打算使用不同于函数。
这个答案可能不尽如人意;你在寻找直觉吗?如果是这样,我建议做很多例子,尤其是阅读LYAH。很难直观地理解像monads这样的抽象事物而没有扎实的实例和经验基础。
为什么我们甚至需要monad?这是一个很好的问题,也许这里有不止一个问题:
为什么我们甚至需要Monad类型?出于同样的原因我们需要任何类型类。
为什么我们甚至需要monad概念?因为它很有用。此外,它不是一个功能,因此它不能被一个功能所取代。 (你的例子似乎不需要一个Monad(相反,它需要一个Applicative))。
例如,您可以使用Applicative类型类实现无上下文解析器组合器。但是尝试在没有Monad的情况下为由相同的符号串组成的语言(由空格分隔)实现一个解析器,即:
a a -> yes
a b -> no
ab ab -> yes
ab ba -> no
这是monad提供的一件事:能够使用以前的结果来决定""决定"该怎么办。这是另一个例子:
f :: Monad m => m Int -> m [Char]
f m =
m >>= \x ->
if x > 2
then return (replicate x 'a')
else return []
f (Just 1) -->> Just ""
f (Just 3) -->> Just "aaa"
f [1,2,3,4] -->> ["", "", "aaa", "aaaa"]
答案 1 :(得分:0)
Monads (以及 Functors 和 Applicative Functors )可以看作是关于“ 广义”功能应用的”:它们都创建类型为 f a ⟶ f b
的函数,其中不仅是“上下文中的值”,例如类型为 a
和 { {1}} ,但也涉及由 b
表示的“上下文”(即相同的上下文)。
因此“普通”功能应用程序涉及类型为 f
的功能,“通用”功能应用程序具有类型为 (a ⟶ b)
的功能。由于更统一的类型结构: (f a ⟶ f b)
。
三个 的每一个都以不同的方式创建它们,从不同的事物开始:>
f a ⟶ f b ; f b ⟶ f c ==> f a ⟶ f c
实际上,区别在于我们如何使用所产生的上下文中值类型,这被视为表示某种类型的计算。
以广义Functors: fmap :: Functor f => (a ⟶ b) ⟶ (f a ⟶ f b)
Applicative Functors: (<*>) :: Applicative f => f (a ⟶ b) ⟶ (f a ⟶ f b)
Monadic Functors: (=<<) :: Monad f => (a ⟶ f b) ⟶ (f a ⟶ f b)
书写方式
do
及其类型,
Functors: do { x <- a ; return (g x) } g <$> a
Applicative do { x <- a ; y <- b ; return (g x y) } g <$> a <*> b
Functors: (\ x -> g x <$> b ) =<< a
Monadic do { x <- a ; y <- k x ; return (g x y) } (\ x -> g x <$> k x) =<< a
Functors: