就OOP程序员所理解的而言(没有任何函数编程背景),monad是什么?
它解决了什么问题,它使用的最常见的地方是什么?
编辑:
为了澄清我一直在寻找的理解,让我们假设您正在将具有monad的FP应用程序转换为OOP应用程序.你会怎么做把monad的职责移植到OOP应用程序?
我对Haskell并不十分精通,所以这可能是一个非常简单的问题.
Rank2Types解决了什么语言限制?Haskell中的函数是否已经支持多态参数?
每当有人承诺"解释monad"时,我的兴趣就会被激怒,只有当被指称的"解释"是一长串的例子时才会被沮丧所取代,这些例子是由一些副手的评论所终止的,即"数学理论"背后的"深奥"在这一点上,"是"太复杂而无法解释".
现在我要求相反的事情.我对类别理论有着扎实的把握,我并不害怕图表追逐,Yoneda的引理或衍生的函子(实际上是在分类意义上的monad和adjunction).
有人能给我一个清晰简洁的定义monad在函数式编程中的含义吗?越少越好的例子:有时一个清晰的概念说明了一百多个胆小的例子.尽管我不挑剔,但Haskell作为演示语言会做得很好.
有人可以简单地解释两者之间的区别吗?我并没有完全理解monad是endofunctor而不仅仅是functor的部分.
考虑以下签名 foldMap
foldMap :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
Run Code Online (Sandbox Code Playgroud)
这与"绑定"非常相似,只是交换了参数:
(>>=) :: Monad m => m a -> (a -> m b) -> m b
Run Code Online (Sandbox Code Playgroud)
在我看来,有因此必须有某种关系的Foldable
,Monoid
和Monad
,但在超我找不到它.据推测,我可以将其中的一个或两个转换为另一个,但我不确定如何.
这种关系可以详细说明吗?
我最近试图找到一个关于monad和monoids之间差异的好消息来源.
有人可以提供关于这方面的良好资源的链接,或者花一点时间来详细说明相似之处/差异吗?
我有一个表示DB记录的字符串ID列表.我想异步地从数据库加载它们,然后异步上传每个记录到远程服务器,然后当完成所有记录上传后,记录上传的记录的ID.
由于我使用的是Scala 2.9.2,我使用的是Twitter的core-util Future实现,但它应该与Monadic转换的2.10期货完全一样.
一般概念是这样的:
def fetch(id: String): Future[Option[Record]]
def upload(record: Record): Future[String]
def notifyUploaded(ids: Seq[String]): Unit
val ids: Seq[String] = ....
Run Code Online (Sandbox Code Playgroud)
我试图通过for comprehension来做到这一点,但fetch返回Future of Option这一事实使得它变得模糊不清并且代码无法编译:
for {
id <- ids
maybeRecord <- fetch(id)
record <- maybeRecord
uploadedId <- upload(record)
} yield uploadedId
Run Code Online (Sandbox Code Playgroud)
编译此结果会导致以下错误:
scala: type mismatch;
found : com.twitter.util.Future[String]
required: Option[?]
uploadedId <- upload(record)
^
Run Code Online (Sandbox Code Playgroud)
我错过了什么?为什么编译器期望uploadedId是一个选项?有什么好办法可以解决这个问题吗?
我是一个有点经验的函数式程序员,但我一直对声明 \xe2\x80\x9cA monad is just a monoid in the Category of endofunctors\xe2\x80\x9d 以及 Haskell 中 monads/functors 的实际实现感到困惑其他函数式语言。
\n根据 Haskell Wiki,\n https://wiki.haskell.org/Functor
\nclass Functor f where\n fmap :: (a -> b) -> f a -> f b\n (<$) :: a -> f b -> f a\n
Run Code Online (Sandbox Code Playgroud)\n函子必须保留恒等态射
\nfmap id = id\n
Run Code Online (Sandbox Code Playgroud)\n函子保留态射的组成
\nfmap (f . g) == fmap f . fmap g\n
Run Code Online (Sandbox Code Playgroud)\n我很明白这一点,所以不需要进一步解释;然而,当我们使用 monad 运算符时>>=
,现在我们有了 Monad 实现和 Monad 法则
monads haskell functional-programming functor category-theory
在Frisby 教授介绍可组合功能JavaScript中引入了身份仿函数:
const Box = x =>
({
map: f => Box(f(x)),
fold: f => f(x) // for testing
})
Run Code Online (Sandbox Code Playgroud)
我花了大部分时间来理解函子以及为什么上面的JavaScript代码实际上是身份函子.所以我想我会改变它以获得一个不是身份函子的"真正的"函子.我想出了这个:
const Endo = x =>
({
map: f => Endo(f(x).split('')),
fold: f => f(x).split('') // for testing
})
Run Code Online (Sandbox Code Playgroud)
我的理由是用Box,Id_Box: Box -> Box
和Id_Box f = f
.远藤也会映射到自己,但Endo(f): Endo(x) -> Endo(y)
(如果f: x -> y
).
我是在正确的轨道上吗?
编辑:替换为原始示例中string
的更通用x
.
haskell ×6
monads ×6
functor ×2
scala ×2
c# ×1
foldable ×1
free-monad ×1
future ×1
javascript ×1
monoids ×1
oop ×1
polymorphism ×1
static ×1
types ×1