首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Scalaz(12)- Monad:再述述flatMap,顺便了解MonadPlus

Scalaz(12)- Monad:再述述flatMap,顺便了解MonadPlus

作者头像
用户1150956
发布于 2018-01-05 02:02:14
发布于 2018-01-05 02:02:14
1K00
代码可运行
举报
运行总次数:0
代码可运行

  在前面的几篇讨论里我们初步对FP有了些少了解:FP嘛,不就是F[A]吗?也是,FP就是在F[]壳子(context)内对程序的状态进行更改,也就是在F壳子(context)内施用一些函数。再直白一点就是在F壳子内进行OOP惯用的行令编程(imperative programming)。当然,既然是在壳子(context)内进行编程这种新的模式,那么总需要些新的函数施用方法吧。我们再次审视一下以前了解过的FP函数施用方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1 1 // Functor    :  map[A,B]    (F[A])(f:   A => B):  F[B]
2 2 // Applicative:  ap[A,B]     (F[A])(f: F[A => B]): F[B] 
3 3 // Monad      :  flatMap[A,B](F[A])(f: A => F[B]): F[B]

它们分别代表了scalaz的三个typeclass。对于FP编程来讲,函数施用(function application)就是改变程序状态,也就是map。那么从map角度分析,如果直接对F[A=>B], A=>F[B]进行map会产生不同的结果类型,如直接map A=>F[B]结果是F[F[B]]。所以我们会想办法把结果类型对齐了,使最终结果类型为F[B]:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1 def ap[A,B](ma: F[A])(mf: F[A => B]): F[B] = mf.flatMap(f => ma.flatMap(a => point(f(a)))  
2  def flatMapByJoin[A,B](ma: M[A])(f: A => M[B]): M[B] = join(map(ma)(a => f(a)))
3  def join[A](mma: M[M[A]]): M[A]

从上面的代码中我们看到:在flatMap我们通过join施用了map。而这个join好像就是为了把F[F[B]]打平到F[B]而设计的,这点从join函数款式(signature)可以看出。难道FP就是为了实现类型匹配吗?绝不是!我们不能把眼光局限在如何取得类型匹配上,而是应该放阔到函数施用的目的上。我们从上面函数map,ap,flatMap的类型款式可以看出:map,ap都是在F[]壳(context)内施用的,而flatMap是在壳外对输入的类型A值进行施用的,但把结果放入了壳内。这可以说是flatMap与map,ap的根本不同之处。那么flatMap代表着什么呢?如果从flatMap的函数款式(function signature)分析:它是一个递归算法: 给F[A]一个A产生F[B],再给F[B]一个B再产生F[C]...如此类推。这样看来flatMap是一个持续算法(computational continuation),如果把flatMap串联起来就可以实现某种编程语法(syntax)。这个推论在scala的for-comprehension中得到证实:flatMap可以被视作一种简单的FP语法,它使我们可以在for-comprehension中使用我们熟悉的行令编程,其结果是FP模式的行令编程。flatMap是Monad的标识函数,而Monad又具备所有的FP函数施用方法因为它继承了Functor和Applicative,所以有些人把FP编程称为Monadic programming。从这里也可以看到flatMap在FP编程里的重要性。

如果从flatMap代表持续算法这个角度分析:flatMap实际连接了两个算法F[A] => F[B]。我们应该可以在运算flatMap的过程中实现一些附加的效果。这个要求应该可以在实现flatMap函数时做到。我们这篇讨论的重点就是在示范如何在实现flatMap时增加一些效果。当把一串算法用flatMap链接起来时这些附加效果是如何积累的。

我想没什么比logger更能示范串接算法前面算法的一些效果是如何流转到下面的算法里的。我们来设计一个例子:模拟一个输入装置,每接收一次输入代表一次运算,用一个logger把每次运算的输入都记录下来。当然,这个例子用State Monad就很容易实现。不过我们的目的是去示范如何通过flatMap把效果传递下去的,所以还是应该紧贴着如何实现flatMap:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 trait KeyLog[K] {
 2   def value: K
 3   def log: String
 4   override def toString = "["+value+","+log+"]"
 5 }
 6 object KeyLog {
 7     def apply[K](k: K, msg: String): KeyLog[K] = new KeyLog[K] {
 8         def value = k
 9         def log = msg
10     }
11 }
12 
13 KeyLog(3,"Entered Number 3")                      //> res0: Exercises.keylog.KeyLog[Int] = [3,Entered Number 3]
14 KeyLog("Hello", "Entered String 'Hello'")         //> res1: Exercises.keylog.KeyLog[String] = [Hello,Entered String 'Hello']

我们用KeyLog[K]来代表这个输入算法。每个算法都包含一个K类型的value和String类型的log。对于类型参数K我们可以直接用普通的flatMap K => KeyLog[I]来转变value。而我们的目的是如何通过flatMap把前一个KeyLog的log累积到下个算法的log。挺简单,是吧?在KeyLog结构里转变log并把结果留在KeyLog里,听着像是map,不过map是针对K的。所以我们要先加个mapLog:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1 trait KeyLog[K] {
2   def value: K
3   def log: String
4   override def toString = "["+value+","+log+"]"
5   def mapLog(preLog: String): KeyLog[K] = KeyLog(value,preLog +";"+log)
6 }

我们试着实现flatMap:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1 trait KeyLog[K] {
2   def value: K
3   def log: String
4   override def toString = "["+value+","+log+"]"
5   def mapLog(preLog: String): KeyLog[K] = KeyLog(value,preLog +";"+log)
6   def flatMap[I](f: K => KeyLog[I]): KeyLog[I] =
7     f(value).mapLog(log)
8 }

确实简单又直接:f(value) 产生 KeyLog[I] 然后在这个接着的算法中调用 mapLog 把上一个算法KeyLog[K]的log并入KeyLog[I]的log。

我们试着用一下flatMap

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1 KeyLog(3,"Entered Number 3").flatMap(a => KeyLog("Hello", "Entered String 'Hello'"))
2                                                   //> res2: Exercises.keylog.KeyLog[String] = [Hello,Entered Number 3;Entered Stri
3                                                   //| ng 'Hello']

最终log值:"Entered Number 3;Entered String 'Hello'。我们实现了在运算flatMap过程中对log进行的累积。

现在我们可以先获取KeyLog的Monad实例,然后进行flatMap串联及使用for-comprehension进行行令编程了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 object KeyLog {
 2     def apply[K](k: K, msg: String): KeyLog[K] = new KeyLog[K] {
 3         def value = k
 4         def log = msg
 5     }
 6 import scalaz._
 7 import Scalaz._
 8     implicit object keylogMonad extends Monad[KeyLog] {
 9         def point[K](k: => K): KeyLog[K] = KeyLog(k,"")
10         def bind[K,I](kk: KeyLog[K])(f: K => KeyLog[I]): KeyLog[I] = kk flatMap f
11     }
12 }

在KeyLog Monad实例里bind使用了我们设计的flatMap函数。看看flatMap串接和for-comprehension效果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def enterInt(k: Int): KeyLog[Int] = KeyLog(k, "Number:"+k.toString)
                                                  //> enterInt: (k: Int)Exercises.keylog.KeyLog[Int]
def enterStr(k: String): KeyLog[String] = KeyLog(k,"String:"+k)
                                                  //> enterStr: (k: String)Exercises.keylog.KeyLog[String]
enterInt(3) >>= {a => enterInt(4) >>= {b => enterStr("Result:") map {c => c + (a * b).toString} }}
                                                  //> res3: Exercises.keylog.KeyLog[String] = [Result:12,Number:3;Number:4;String:
                                                  //| Result:;]
for {
 a <- enterInt(3)
 b <- enterInt(4)
 c <- enterStr("Result:")
} yield c + (a * b).toString                      //> res4: Exercises.keylog.KeyLog[String] = [Result:12,Number:3;Number:4;String
                                                  //| :Result:;]

value和log都按照要求实现了转变。

在使用for-comprehension时突然想到守卫函数(guard function)。我想既然已经得到了KeyLog的Monad实例,是不是可以在它的for-comprehension里使用守卫函数呢?就像这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1 for {
2  a <- enterInt(3)
3  b <- enterInt(4)  if b > 0
4  c <- enterStr("Result:")
5 } yield c + (a * b).toString

不过无法通过编译。提示需要filter函数。查了一下MonadPlus typeclass可以提供这个函数。那么我们就沿着惯用的套路获取一下KeyLog的MonadPlus实例。MonadPlus trait的定义如下:scalaz/MonadPlus.scala

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 trait MonadPlus[F[_]] extends Monad[F] with ApplicativePlus[F] { self =>
 2   ////
 3 
 4   /** Remove `f`-failing `A`s in `fa`, by which we mean: in the
 5     * expression `filter(filter(fa)(f))(g)`, `g` will never be invoked
 6     * for any `a` where `f(a)` returns false.
 7     */
 8   def filter[A](fa: F[A])(f: A => Boolean) =
 9     bind(fa)(a => if (f(a)) point(a) else empty[A])
10 ...

MonadPlus又继承了ApplicativePlus:scalar/ApplicativePlus.scala

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1 trait ApplicativePlus[F[_]] extends Applicative[F] with PlusEmpty[F] { self =>

ApplicativePlus又继承了PlusEmpty: scalaz/PlusEmpty.scala

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1 trait PlusEmpty[F[_]] extends Plus[F] { self =>
2   ////
3   def empty[A]: F[A]
4 ...

PlusEmpty定义了抽象成员empty[A],又继承了Plus: scalar/Plus.scala

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 trait Plus[F[_]]  { self =>
 2   ////
 3 
 4   /**The composition of Plus `F` and `G`, `[x]F[G[x]]`, is a Plus */
 5   def compose[G[_]](implicit G0: Plus[G]): Plus[({type λ[α] = F[G[α]]})] = new CompositionPlus[F, G] {
 6     implicit def F = self
 7 
 8     implicit def G = G0
 9   }
10 
11   /**The product of Plus `F` and `G`, `[x](F[x], G[x]])`, is a Plus */
12   def product[G[_]](implicit G0: Plus[G]): Plus[({type λ[α] = (F[α], G[α])})] = new ProductPlus[F, G] {
13     implicit def F = self
14 
15     implicit def G = G0
16   }
17 
18   def plus[A](a: F[A], b: => F[A]): F[A]
19 
20   def semigroup[A]: Semigroup[F[A]] = new Semigroup[F[A]] {
21     def append(f1: F[A], f2: => F[A]): F[A] = plus(f1, f2)
22   }
23 ...

Plus又定义了抽象成员plus[A],那么获取MonadPlus实例必须实现empty[A]: F[A]和plus[A](a: F[A], b: F[A]): F[A]。看来这个PlusEmpty就是一种Monoid,只不过是针对高阶类型的。我们知道Monad实例类型必须是高阶的M[_],那么如果Monad实例同时又具备Monoid特性的话,那么就可以使用MonadPlus来描述它的性质。

好了,现在我想获取KeyLog[K]的MonadPlu实例,那么我必须实现empty[A]:F[A]和plus[A](a:F[A],b:F[A]):F[A]。KeyLog[K]的empty[K]是什么呢?想了半天没得到答案,可能KeyLog[K]就没有empty[K]吧。也许我们想取得KeyLog MonadPlu实例的目的还没搞清楚。看看上面的需求:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1 for {
2  a <- enterInt(3)
3  b <- enterInt(4)  if b > 0
4  c <- enterStr("Result:")
5 } yield c + (a * b).toString

从字面上看是希望通过守卫函数过滤数字为0的数字。等等,enterInt(4)已经确定了输入为4,是 > 0,还过滤什么?不是找事吗。所以我们的目的应该聚焦在过滤需求上。Scalaz为List,Option提供了MonadPlus实例,我们看看这两种类型的守卫函数使用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 for { //list
 2     a <- 1 |-> 50 if a.shows contains '7'
 3 } yield a                                         //> res5: List[Int] = List(7, 17, 27, 37, 47)
 4 for { //option
 5     a <- Some(3)
 6     b <- Some(4) if a < b
 7 } yield b                                         //> res6: Option[Int] = Some(4)
 8 for { //option
 9     a <- Some(3)
10     b <- Some(4) if a > b
11 } yield b                                         //> res7: Option[Int] = None

先来分析List例子:一个List可能是空的,又可能有多过一个元素,有多种可能。守卫函数的功能就是在这些可能里进行选择。

再分析Option:可能是None或者Some,这本身就是一种筛选。对于KeyLog[K],它只有一种状态,没有选择的需要,所以我无法实现KeyLog[K]的empty[K]。

List和Option的empty分别是:Nil和None,这个很容易理解。那么plus呢?把 plus(list1,list2):list3 = list1 ++ list2这个倒是容易理解,但plus(option1,option2):option3这个又应该怎么理解呢?我们还是看看在scalaz里是怎么定义plus的吧:scalaz.std/List.scala

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1   implicit val listInstance = new Traverse[List] with MonadPlus[List] with Each[List] with Index[List] with Length[List] with Zip[List] with Unzip[List] with Align[List] with IsEmpty[List] with Cobind[List] {
2 ...
3     def empty[A] = Nil
4     def plus[A](a: List[A], b: => List[A]) = a ++ b
5 ...

List的plus就是把两个List接起来(concat)

scalaz.std/Option.scala

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1   implicit val optionInstance = new Traverse[Option] with MonadPlus[Option] with Each[Option] with Index[Option] with Length[Option] with Cozip[Option] with Zip[Option] with Unzip[Option] with Align[Option] with IsEmpty[Option] with Cobind[Option] with Optional[Option] {
2 ...
3     def empty[A]: Option[A] = None
4     def plus[A](a: Option[A], b: => Option[A]) = a orElse b
5 ...

Option的plus意思是如果a是None就取b否则取a,无论b是否None。我们用MonadPlus提供的操作符号<+>来示范:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1 List(1,2,3) <+> List(4,5,6)                       //> res4: List[Int] = List(1, 2, 3, 4, 5, 6)
2 Nil <+> List(1,2,3)                               //> res5: List[Int] = List(1, 2, 3)
3 List(1,2,3) <+> Nil                               //> res6: List[Int] = List(1, 2, 3)
4 none <+> 2.some                                   //> res7: Option[Int] = Some(2)
5 2.some <+> 3.some                                 //> res8: Option[Int] = Some(2)
6 2.some <+> none                                   //> res9: Option[Int] = Some(2)
7 none <+> none                                     //> res10: Option[Nothing] = None

为了实现KeyLog MonadPlus实例,我们必须对KeyLog类型重新定义使之包含多过一种状态:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 import scalaz._
 2 import Scalaz._
 3 object keylog {
 4 trait KeyLog[+K] {
 5   override def toString = this match {
 6     case KeyIn(value,log) => "["+value+","+log+"]"
 7     case _ => "[Keypad Locked]"
 8   }
 9   def mapLog(preLog: String): KeyLog[K] = this match {
10     case KeyIn(value,log) => KeyIn(value,preLog +";"+log)
11     case _ => KeyLock
12   }
13   def flatMap[I](f: K => KeyLog[I]): KeyLog[I] = this match {
14     case KeyIn(value,log) => f(value).mapLog(log)
15     case _ => KeyLock
16   }
17 }
18 case class KeyIn[K](value: K, log: String) extends KeyLog[K]
19 case object KeyLock extends KeyLog[Nothing]
20 object KeyLog {
21 /*    def apply[K](k: K, msg: String): KeyLog[K] = new KeyLog[K] {
22         def value = k
23         def log = msg
24     } */
25     implicit object keylogMonad extends Monad[KeyLog] {
26         def point[K](k: => K): KeyLog[K] = KeyIn(k,"")
27         def bind[K,I](kk: KeyLog[K])(f: K => KeyLog[I]): KeyLog[I] = kk flatMap f
28     }
29 }

我们增加了KeyIn和KeyLock两种状态。然后我们只需要通过模式匹配(pattern matching)在实现前面逻辑的时候把多种KeyLog状态考虑进去。

运行前面的例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 def enterInt(k: Int): KeyLog[Int] = KeyIn(k, "Number:"+k.toString)
 2                                                   //> enterInt: (k: Int)Exercises.keylog.KeyLog[Int]
 3 def enterStr(k: String): KeyLog[String] = KeyIn(k,"String:"+k)
 4                                                   //> enterStr: (k: String)Exercises.keylog.KeyLog[String]
 5 enterInt(3) >>= {a => enterInt(4) >>= {b => enterStr("Result:") map {c => c + (a * b).toString} }}
 6                                                   //> res0: Exercises.keylog.KeyLog[String] = [Result:12,Number:3;Number:4;String
 7                                                   //| :Result:;]
 8 for {
 9  a <- enterInt(3)
10  b <- enterInt(4)
11  c <- enterStr("Result:")
12 } yield c + (a * b).toString                      //> res1: Exercises.keylog.KeyLog[String] = [Result:12,Number:3;Number:4;String
13                                                   //| :Result:;]

 现在把KeyLock效果加进去:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1 enterInt(3) >>= {a => (KeyLock: KeyLog[Int]) >>= {b => enterStr("Result:") map {c => c + (a * b).toString} }}
2                                                   //> res2: Exercises.keylog.KeyLog[String] = [Keypad Locked]
3 for {
4  a <- enterInt(3)
5  b <- enterInt(4)
6  x <- (KeyLock: KeyLog[String])
7  c <- enterStr("Result:")
8 } yield c + (a * b).toString                      //> res3: Exercises.keylog.KeyLog[String] = [Keypad Locked]

正是我们期待的效果。

现在我们可以把MonadPlus特质混入keylogMonad实例(trait mix-in):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1     implicit object keylogMonad extends Monad[KeyLog] with MonadPlus[KeyLog] {
 2         def point[K](k: => K): KeyLog[K] = KeyIn(k,"")
 3         def bind[K,I](kk: KeyLog[K])(f: K => KeyLog[I]): KeyLog[I] = kk flatMap f
 4 
 5         def empty[K]: KeyLog[K] = KeyLock
 6         def plus[K](a: KeyLog[K], b: => KeyLog[K]): KeyLog[K] = a match {
 7             case KeyIn(value,log) => KeyIn(value,log)
 8             case KeyLock => b
 9         }
10     }

在实例中我们实现了empty和plus。

那么现在我们可以使用守卫函数了吧:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 for {
 2  a <- enterInt(3)
 3  b <- enterInt(4)
 4  c <- enterStr("Result:")
 5 } yield c + (a * b).toString                      //> res3: Exercises.keylog.KeyLog[String] = [Result:12,Number:3;Number:4;String
 6                                                   //| :Result:;]
 7 for {
 8  a <- enterInt(3)
 9  b <- enterInt(4) if b > 0
10  c <- enterStr("Result:")
11 } yield c + (a * b).toString                      //> res4: Exercises.keylog.KeyLog[String] = [Result:12,Number:3;Number:4;;Strin
12                                                   //| g:Result:;]
13 for {
14  a <- enterInt(3)
15  b <- enterInt(4) if b > 5
16  c <- enterStr("Result:")
17 } yield c + (a * b).toString                      //> res5: Exercises.keylog.KeyLog[String] = [Keypad Locked]

守卫函数按要求对KeyLog状态进行了过滤。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015-11-13 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
全面布局“边” “端”,腾讯云边缘计算技术探索及落地应用
我们已经进入了中心与边缘互相协作,共同助力各行各业数字化转型的时代。随着物联网的发展,未来的网络结构必定是“云—边—端”的模式。腾讯云在强大的云端能力之外,正在全面布局“边“和“端”的计算能力,为即将到来的万物智联时代提供技术和平台支持。
用户1532637
2018/06/06
3.5K0
从中心走向边缘——解读边缘计算解决方案!
导语 | 中心云计算正如火如荼竞争着,边缘云竞争又开始了。本文主要内容是介绍掌握业务上云必备知识云计算及服务模式;以及基于边缘计算“云-边-端”的框架,理解软硬一体解决方案;再结合在自动驾驶场景下的交付落地,了解“边缘计算+5G+AI”能做什么。 引言 (一)云计算定义 云计算的概念是Google CEO埃里克于2006年提出的,同年AWS成立云计算落地。根据美国国家标准与技术研究院NIST定义,云计算是一种按需使用,按量付费的服务模式,提供可用的、便捷的、按需的网络访问,可配置的计算资源共享池。 (二)服
腾讯云开发者
2022/04/01
3K0
从中心走向边缘——解读边缘计算解决方案!
解读 | 基于CDN的边缘计算平台设计和思考
CDN的重要性不仅仅在于CDN的业务本身,更重要的是CDN的基础设施属性,CDN节点是全球分布的,随着5G的正式商用,目前来看,CDN的规模最大、算力最强,将成为布局边缘计算最佳的位置。但是边缘计算不是孤立存在,是必须跟云中心协同的。本文介绍从CDN的角度思考如何打造一个云边端协同的边缘计算平台。
CloudBest
2020/09/30
2.4K0
解读 | 基于CDN的边缘计算平台设计和思考
基于CDN的边缘计算平台设计和思考
CDN的全称是ContentDelivery Network,即内容分发网络。CDN是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN的关键技术主要有内容存储和分发技术。
边缘计算
2019/12/12
2.6K0
2022中国边缘计算企业20强
边缘计算社区长期致力于推进边缘计算领域知识传播和生态发展建设。从2019年起每年年中发布 “边缘计算20强企业榜单” 。设立“边缘计算榜单”的目的是为了推动边缘计算行业的宣传和普及,让更多人有机会了解边缘计算行业的发展现状、优秀企业和创新产品,从而促进边缘计算行业更好的发展。
边缘计算
2022/05/17
1.2K0
2022中国边缘计算企业20强
边缘计算场景下云边端一体化的挑战与实践
作者王继罗,腾讯云专家工程师,腾讯边缘 Kubernetes 管理平台 TKE Edge 技术负责人,SuperEdge 边缘容器开源项目发起人之一。 本文整理自腾讯云专家工程师王继罗在 2020年12月深圳 Qcon 大会上的分享内容——边缘计算场景下云边端一体化的挑战与实践 。 边缘计算想必大家都已经听过了,但是如何将业务扩展到边缘,从而实现更大的业务价值呢? 关于这个问题,腾讯云早在几年前就已开始进行思考,并且着手打造了云边端一体化的超融合平台,目的是希望能够让业务可以更容易落地到边缘。 今天,我们
腾讯云原生
2021/02/04
4K0
边缘计算,是物联网的下一个爆发点吗?
导语 | 从万物互联到万物智联的转向升级中,边缘计算与物联网的结合备受关注。本文由腾讯云边缘计算高级产品经理彭超在 Techo TVP 开发者峰会“「物」所不在,「联」动未来——从万物互联到万物智联”上的演讲《边缘计算:AIoT的下一个爆发点》整理而成,向大家普及边缘计算这项新兴技术,并深入分析边缘计算如何助力万物智联。 点击可观看精彩演讲视频 一、边缘计算的概述 这个章节主要给大家介绍边缘计算的概念及腾讯云在边缘计算赛道的思考和方向。 如上图所示,这是边缘计算的整体架构,最左侧是生产端设备,最
腾讯云开发者
2021/12/01
1.3K0
2018上半年边缘计算领域巨头都干了啥?
边缘计算市场吸引了许多知名企业,包括AWS、思科、华为、IBM、英特尔、微软等,各类边缘计算的“玩家”们在2018年上半年做了什么? 边缘计算市场前景及估值 边缘计算(Edge computing),
边缘计算
2019/07/03
8210
2018上半年边缘计算领域巨头都干了啥?
边缘计算万亿级市场的“玩家”们,2018年上半年都干了啥?
边缘计算(Edge computing),是一种分散式运算的架构,它将应用程序、数据资料与服务的运算,由网络中心节点,移往网络逻辑上的边缘节点来处理。边缘计算能提高数据处理能力,使数据处理最接近数据源,从而提供更好的性能和实时体验。据IDC统计数据显示,到2020年将有超过500亿的终端和设备联网,其中超过50%的数据需要在网络边缘侧分析、处理与存储,边缘计算市场之大,可超万亿。也正是如此,各大巨头纷纷发力边缘计算,边缘计算市场吸引了许多知名企业,包括AWS、思科、华为、IBM、英特尔、微软等,下面盘点各类边缘计算的“玩家”们,看看2018年上半年他们做了什么。
SDNLAB
2018/07/30
1.2K0
边缘计算万亿级市场的“玩家”们,2018年上半年都干了啥?
共享经济模式下的边缘计算——PPIO边缘云 laaS技术实践分享
大家好,我是王闻宇。非常感谢LiveVideoStack的邀请,也非常荣幸今天能和大家一起分享交流。
LiveVideoStack
2021/11/26
1.8K0
边缘计算,行业创新载体
MEC的引入为行业业务提供了一种新的服务,通过MEC分流实现公网服务专网,提供超低时延的本地准专属网络;分布式边缘云基础设施为跨多地行业应用提供按需、便捷的边缘云服务;集成行业通用引擎,为上层业务快速开发与开展提供快速支撑。
边缘计算
2019/11/28
2.2K0
5G时代的边缘计算丨文末赠书
本文选自最近人民邮电出版社新书《从云端到边缘:边缘计算的产业链与行业应用》第一章第二节“5G时代的边缘计算”,作者吴冬升,5G产业技术联盟车联网专委会主任委员,现任高新兴科技集团股份有限公司高级副总裁。
边缘计算
2021/11/23
5810
边缘节点的需求分析和核心技术研究
本文分析了来自5G、IoT 和CDN的边缘计算需求,对边缘计算的总体架构进行了研究。边缘节点作为数据中心网络中的一个重要组成部分,边缘硬件、边云协同和边边协同的技术发展将会非常重要。未来,需要解决好技术碎片化和布局等问题,促进边缘节点的更快发展。
边缘计算
2020/05/18
1.5K0
边缘计算成为下一个爆发点,云计算巨头和CDN巨头谁会赢?
在最近一次云栖大会上,阿里巴巴集团资深副总裁、阿里云总裁胡晓明宣布,IoT(物联网)正式成为阿里巴巴在电商、金融、物流、云计算后的主战略,而为了做好IoT,阿里云将在2018年战略投入“边缘计算”这一新兴技术领域。 不只是阿里云,被媒体称为“3A”的云计算三巨头,包括亚马逊AWS、微软AZURE,都已在边缘计算上进行战略布局,边缘计算这个由IBM在2012年提出的概念,一直到2017年才真正迎来爆发,而理论上来看,边缘计算与云计算是竞争关系,云计算巨头为何都要战略布局边缘计算呢? 为什么说边缘计算会爆发
罗超频道
2018/04/25
1.5K0
边缘计算成为下一个爆发点,云计算巨头和CDN巨头谁会赢?
边缘计算核心技术辨析
边缘计算(Edge Computing)是云计算向边缘的延伸,本文对边缘计算、雾计算、MEC、Cloudlet、分布式云等边缘计算领域相关概念和技术的定义、架构、场景等进行了比较分析,并对该领域的技术发展趋势给出了预测与展望。
边缘计算
2019/10/08
1K0
边缘计算核心技术辨析
诚意之作,老司机带你入门边缘计算
边缘计算一词现在十分火热,加上10月份OpenStack基金会另一边缘计算开源项目StarlingX的发布引发了广泛的关注,所以SDNLAB为大家邀请了英特尔开源技术中心研发经理、OpenStack基金会个人独立董事——王庆,在全新升级的壹课Online频道为大家免费直播讲解《边缘计算和StarlingX》,下面是根据分享内容整理的文字。
SDNLAB
2018/12/29
2K0
面向 5G 的边缘计算及部署思考
摘要:边缘计算对于运营商而言是一种网络架构和业务模式的创新。基于运营商的运维需求,针对5G的边缘计算提出了一套系统化的解决方案。5G 边缘计算的部署基于业务需求和场景,并结合网络需求、边缘基础设施、运营模式及维护管理需要,是性能与投资的均衡考虑。强大的生态系统是 5G 边缘计算发展的保障,完善的基础设施、灵活的网络和平台能力以及丰富的边缘应用是推动边缘生态繁荣的关键因素。
边缘计算
2019/08/12
1.2K0
面向 5G 的边缘计算及部署思考
云游戏全景分析
从2019年开始,IT行业普遍焦虑,大家都讲不出4G的新故事,只能寄希望于5G应用。更多人对云游戏的“火爆”,是对所有和5G沾边的新闻一样盲目的狂热,至少不能显得自己落伍了。
赵成
2020/02/12
2.3K0
云游戏全景分析
5G边缘计算的发展前景与应用
5月30日上午,由工控兄弟连主办的“新工业 智物联”全国巡回研讨会南京站在1865科技产业创意产业园举行,会议就工业互联、物联网、智能制造行业的未来发展进行交流讨论。小枣君应邀参加大会CEO闭门峰会论坛,并做“5G边缘计算的发展前景与应用”主题演讲。
鲜枣课堂
2019/07/20
1.1K0
【从0到1学习边缘容器系列】之 边缘计算与边缘容器的起源
作者王继罗,腾讯云技术专家,曾就职于阿里巴巴、字节跳动、映客直播,一直从事基础架构平台方面的工作,目前负责腾讯边缘 Kubernetes 管理平台 TKE@edge。
腾讯云原生
2020/05/26
1.7K0
【从0到1学习边缘容器系列】之 边缘计算与边缘容器的起源
推荐阅读
相关推荐
全面布局“边” “端”,腾讯云边缘计算技术探索及落地应用
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档