在C#中,什么是单子? [英] In C#, What is a monad?

查看:132
本文介绍了在C#中,什么是单子?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这些天来有很多关于单子的讨论.我已经阅读了几篇文章/博客文章,但是对于他们的例子我无法走得太远,无法完全理解这个概念.原因是monad是功能语言的概念,因此示例使用的是我尚未使用过的语言(因为我没有深入使用功能语言).我无法足够深入地掌握语法,无法完全按照文章进行操作……但是我可以告诉您那里有一些值得理解的地方.

There is a lot of talk about monads these days. I have read a few articles / blog posts, but I can't go far enough with their examples to fully grasp the concept. The reason is that monads are a functional language concept, and thus the examples are in languages I haven't worked with (since I haven't used a functional language in depth). I can't grasp the syntax deeply enough to follow the articles fully ... but I can tell there's something worth understanding there.

但是,我非常了解C#,包括lambda表达式和其他功能.我知道C#仅具有部分功能,因此也许monads无法用C#表示.

However, I know C# pretty well, including lambda expressions and other functional features. I know C# only has a subset of functional features, and so maybe monads can't be expressed in C#.

但是,肯定可以传达这个概念吗?至少我希望如此.也许您可以提出一个C#示例作为基础,然后描述C#开发人员会希望从那里可以做什么,但不能这样做,因为该语言缺少功能性的编程功能.这太棒了,因为它可以传达单子的意图和好处.所以这是我的问题:您可以向C#3开发人员提供monad的最佳解释是什么?

However, surely it is possible to convey the concept? At least I hope so. Maybe you can present a C# example as a foundation, and then describe what a C# developer would wish he could do from there but can't because the language lacks functional programming features. This would be fantastic, because it would convey the intent and benefits of monads. So here's my question: What is the best explanation you can give of monads to a C# 3 developer?

谢谢!

(顺便说一句,我知道SO上至少已经有3个什么是单子"问题.但是,我也面临着同样的问题...所以这个问题是imo所需要的,因为专注于C#开发人员.谢谢.)

( By the way, I know there are at least 3 "what is a monad" questions already on SO. However, I face the same problem with them ... so this question is needed imo, because of the C#-developer focus. Thanks.)

推荐答案

您整天在编程中所做的大部分工作都是将一些函数组合在一起,以从中构建更大的函数.通常,您不仅在工具箱中具有函数,而且还具有运算符,变量赋值之类的其他东西,但是通常,您的程序将许多计算"结合在一起,形成更大的计算量,并将其进一步结合在一起.

Most of what you do in programming all day is combining some functions together to build bigger functions from them. Usually you have not only functions in your toolbox but also other things like operators, variable assignments and the like, but generally your program combines together lots of "computations" to bigger computations that will be combined together further.

monad是实现此计算组合"的某种方式.

A monad is some way to do this "combining of computations".

通常,将两个计算结合在一起的最基本的运算符"是;:

Usually your most basic "operator" to combine two computations together is ;:

a; b

这句话的意思是先做a,然后再做b".结果a; b基本上还是可以与更多内容组合在一起的计算. 这是一个简单的monad,它是将小型计算与大型计算结合的一种方式. ;说先在左边做,然后再在右边做".

When you say this you mean "first do a, then do b". The result a; b is basically again a computation that can be combined together with more stuff. This is a simple monad, it is a way of combing small computations to bigger ones. The ; says "do the thing on the left, then do the thing on the right".

.在面向对象语言中可以看作是monad的另一件事.通常,您会发现以下内容:

Another thing that can be seen as a monad in object oriented languages is the .. Often you find things like this:

a.b().c().d()

.的基本含义是评估左侧的计算,然后根据该结果调用右侧的方法".这是将函数/计算组合在一起的另一种方式,比;稍微复杂一点.将事物与.链接在一起的概念是一个单子,因为它是将两个计算组合在一起形成新计算的一种方式.

The . basically means "evaluate the computation on the left, and then call the method on the right on the result of that". It is another way to combine functions/computations together, a little more complicated than ;. And the concept of chaining things together with . is a monad, since it's a way of combining two computations together to a new computation.

另一种没有特殊语法的相当普通的monad就是这种模式:

Another fairly common monad, that has no special syntax, is this pattern:

rv = socket.bind(address, port);
if (rv == -1)
  return -1;

rv = socket.connect(...);
if (rv == -1)
  return -1;

rv = socket.send(...);
if (rv == -1)
  return -1;

返回值-1表示失败,但是没有真正的方法可以抽象出此错误检查,即使您有许多需要以这种方式组合的API调用也是如此.这基本上只是另一个monad,它通过以下规则组合了函数调用:如果左侧的函数返回-1,则自己返回-1,否则调用右侧的函数".如果我们有一个运算符>>=完成了此任务,我们可以简单地编写:

A return value of -1 indicates failure, but there is no real way to abstract out this error checking, even if you have lots of API-calls that you need to combine in this fashion. This is basically just another monad that combines the function calls by the rule "if the function on the left returned -1, do return -1 ourselves, otherwise call the function on the right". If we had an operator >>= that did this thing we could simply write:

socket.bind(...) >>= socket.connect(...) >>= socket.send(...)

这将使事情更具可读性,并有助于抽象出我们组合功能的特殊方式,这样我们就不需要一遍又一遍地重复自己了.

It would make things more readable and help to abstract out our special way of combining functions, so that we don't need to repeat ourselves over and over again.

还有更多的方法可以组合功能/计算,这些功能/计算可用作一般模式,并且可以在monad中进行抽象,从而使monad的用户可以编写更加简洁明了的代码,因为所有簿记工作并且已使用功能的管理在monad中完成.

And there are many more ways to combine functions/computations that are useful as a general pattern and can be abstracted in a monad, enabling the user of the monad to write much more concise and clear code, since all the book-keeping and management of the used functions is done in the monad.

例如,上面的>>=可以扩展为进行错误检查,然后在获得输入的套接字上调用右侧",因此我们无需显式指定socket时间:

For example the above >>= could be extended to "do the error checking and then call the right side on the socket that we got as input", so that we don't need to explicitly specify socket lots of times:

new socket() >>= bind(...) >>= connect(...) >>= send(...);

正式定义有点复杂,因为您必须担心如何将一个函数的结果作为下一个函数的输入,如果该函数需要该输入,并且您想确保所使用的函数结合适合您尝试将它们组合到monad中的方式.但是,基本概念只是形式化将功能组合在一起的不同方式.

The formal definition is a bit more complicated since you have to worry about how to get the result of one function as an input to the next one, if that function needs that input and since you want to make sure that the functions you combine fit into the way you try to combine them in your monad. But the basic concept is just that you formalize different ways to combine functions together.

这篇关于在C#中,什么是单子?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆