在向某人解释什么是类型类X时,我很难找到正好是X的数据结构的好例子.
所以,我请求示例:
我认为Monad到处都有很多例子,但Monad的一个很好的例子与之前的例子有一些关系可以完成图片.
我寻找彼此相似的示例,区别仅在于属于特定类型类的重要方面.
如果有人能够设法在这个层次结构的某个地方隐藏一个Arrow的例子(它是在Applicative和Monad之间吗?),那也会很棒!
我刚才读从以下typeclassopedia约之间的差异Monad和Applicative.我能理解,没有join在Applicative.但是下面的描述看起来含糊不清,我无法弄清楚monadic计算/动作的"结果"究竟是什么意思.所以,如果我把一个值放入Maybe,这使得一个monad,这个"计算"的结果是什么?
让我们更仔细地看一下(>> =)的类型.基本的直觉是它将两个计算组合成一个更大的计算.第一个参数ma是第一个计算.但是,如果第二个论点只是一个mb,那将是无聊的; 那么计算就无法相互交互(实际上,这正是Applicative的情况).因此,(>> =)的第二个参数具有类型a - > mb:这种类型的函数,给定第一次计算的结果,可以产生第二个要运行的计算....直观地说,正是这种能力使用先前计算的输出来决定接下来运行哪些计算使Monad比Applicative更强大.应用计算的结构是固定的,而Monad计算的结构可以基于中间结果而改变.
是否有一个具体的例子说明"能够使用先前计算的输出来决定接下来要运行的计算",Applicative没有?
我正在寻找以下功能:
Applicative f => f (f a) -> f a
Hoogle告诉我join:
>:t join
join :: Monad m => m (m a) -> m a
Run Code Online (Sandbox Code Playgroud)
有没有符合我想要的签名的功能?
我觉得这个问题很傻,但是我已经想到了一段时间,我找不到任何答案.
所以问题是:为什么应用仿函数有副作用,但仿函数不能?
也许他们可以而且我从未注意到......?
我看到处处Applicative可以处理副作用,但我见过的所有简单例子都是将各种东西组合在一起,如:
> (,,) <$> [1,2] <*> ["a", "b", "c"] <*> ["foo", "bar"]
[(1,"a","foo"),(1,"a","bar"),(1,"b","foo"),(1,"b","bar"),
(1,"c","foo"),(1,"c","bar"),(2,"a","foo"),(2,"a","bar"),
(2,"b","foo"),(2,"b","bar"),(2,"c","foo"),(2,"c","bar")]
Run Code Online (Sandbox Code Playgroud)
哪个很酷,但我看不出它与副作用有何联系.我的理解是,它Applicative是一个弱单子,所以你可以处理副作用(就像你对State monad一样),但你不能重复使用前一个副作用的结果.
这是否意味着>>可以写出Applicative类似的东西
do
print' "hello"
print' "world"
Run Code Online (Sandbox Code Playgroud)
会有意义(有print' :: a -> Applicative something)(使用适当的do-applicative扩展名).
在另一个世界,之间的区别Monad,并Applicative是Monad允许x <- ...,但Applicative没有.
然后,是作家monad,只是一个应用程序?
在这段代码中:
fromMaybe <$> (print "A" >> return True) <*> (print "B" >> (return $ Just False))
fromMaybe <$> (print "A" >> return True) <*> (print "B" >> (return $ Nothing))
Run Code Online (Sandbox Code Playgroud)
我预计,由于懒惰,"A"或"B"将被打印,这取决于我是否提供Just something或者Nothing两者都打印,无论如何.有人可以解释一下这里到底发生了什么?和b)我怎样才能达到我想要的效果?