Monad的重点
Posted 哨兵
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Monad的重点相关的知识,希望对你有一定的参考价值。
Monad是非常强有力的概念,在介绍Monad是什么和如何工作的之前,我们应该先确认Monad能解决什么问题。Monad是各种编程问题的的 meta solution,它不是某种特定问题的解决方案,我们将通过一些例子来介绍Monad.
Monad是使用amplified type组合函数的模式,ampified type可以看做是带一个泛型参数的泛型类型. IEnumerable<T>是个很好的例子。Monad可以去除丑陋和重复的代码,简化很多编程问题的处理。它是来自数学里的范畴论分支里的概念,最初被用在Haskell语言里
通常编程时我们会操作值,值可以是简单的内置于语言的类型,比如,int,bool,string,或者是我们自己定义的复杂类型,比如Customer。这些值会被传递并做各种处理. 最理想的编程是编程语言可以让我们优美的表达我们的目的.
bool IsGreaterThanTen(int value) { return value > 10; }
我们可以很容易使用这个函数:
if(IsGreaterThanTen(x) { //do something )
但是如果我们的函数会抛出 异常呢?
bool IsAFactorOfTwelve(int value) { if(value==0) throw new Exception("Can‘t divide by zero"); return (12 % value ) == 0; }
现在我们必须使用样板式的 Try catch包裹它
try { if(IsAFactorOfTwelve(x)) { //do something } catch(Exception e) { // handle the exception }
如果我们的函数可以返回null呢 ?
string Trim(string value) { if(value==null) return null; return value.Trim(); }
那么我们现在必须要要插入一些样板代码来检查是否是null
var trimmedValue=Trim(inputValue) if(trimmedValue == null) { //so something different here }
每次添加样板代码都会使模糊我们的代码功能,使我们的代码难写难读,而且更容易产生bug。样板式代码与我们的代码功能并不相关,它可能是try-catch块,null检查, 重复,或者其他使我们违反DRY原则的代码
这里有一个更有启迪性的例子。 怎样处理list或者collection呢(如果不使用Linq和相关的扩展方法),任何时候访问List和Collection里的值都需要加一个foreach循环, 这更加样板
foreach(var member in Range(5,10)) { //do something with the number }
IEnumberable<int>是泛型类型,我们也可以认为它是amplified type. 它表示整数的结合而不是单一整数。 我们也可以用amplified type表示其他东西。在上面的Trim例子里我们可以返回一个Nullable<string>(假定Nullable可以用于引用类型), 我们其实增强(amplify)string为一个既可以是string又可以是null的类型。在C#里对于引用类型这种增强是隐式的,如果可以支持直接返回Nullablle的引用类型会更好。
我们也可以想象让IsAFactOfTwelve函数返回一个IMightThrowAnException<bool>,这样会让代码的意图更明确, 它返回一个增强的bool,既可以是bool也可以是一个异常. 当然C#的函数都有一个隐式的Exception返回类型。如果函数签名能告诉我们它可能返回的异常会更好。
Monad使我们可以处理这些amplified type,允许我们去掉样板代码. 它可以帮助我们写声明式的程序,解决程序员的核心问题,控制复杂度,从而使我们的代码更清晰.
以上是关于Monad的重点的主要内容,如果未能解决你的问题,请参考以下文章