Monad在Scala中的应用笔记

Allegro中调整差分对等长的步骤介绍 【代码】Allegro中调整差分对等长的步骤介绍。 阅读详情

这个例子来源于scala圣经级教程《Functional Programming in Scala》,虽然原书的随书代码可以找到这些类的影子,但却没有关于如何使用这些类的示例代码,本人在阅读此书期间,除了跟着书中的代码敲了一遍之外,还写了一些测试代码进行验证,贴出来作为blog主要是为了方便自己,也为那些同样在阅读此书的人参考。注释不多,本人也不可能写太多,因为这本书不是简单的入门书,而是一本进阶,升华用的内涵书籍,三言两语也解释不清其中的很多细节,如果看不懂,但是又感兴趣的就去看原书吧……

  1. Monad是可以认为是这样一种结构,这种结构能够将一个值放入一个可计算的上下文中(A monad is a structure that puts a value in a computational context)。
  2. 通过例子中的idMonad我们可以这样看待monad: monad提供了一个引入和绑定变量的上下文,同时执行了变量替换。idMonad只是使用样列类Id简单的封装了一个值而已,我们完全可以不用Id包装做相同的事情,比如演示用例中,拼接”hello monad”字符串所做的那样!
  3. 类似的,示例中的stateMonad做的事情也是像Id那样执行变量替换,最新的状态可以从一个语句传递到另外一个。

package monad

import monad.Monad.{getState, setState}
import parallelism.Par._
import parallelism._
import parsing._
import testing._
import state._

import scala.language.higherKinds


trait Functor[F[_]] {
  def map[A,B](fa: F[A])(f: A => B): F[B]

  def distribute[A,B](fab: F[(A, B)]): (F[A], F[B]) =
    (map(fab)(_._1), map(fab)(_._2))

  def codistribute[A,B](e: Either[F[A], F[B]]): F[Either[A, B]] = e match {
    case Left(fa) => map(fa)(Left(_))
    case Right(fb) => map(fb)(Right(_))
  }
}

object Functor {
  val listFunctor = new Functor[List] {
    def map[A,B](as: List[A])(f: A => B): List[B] = as map f
  }
}

trait Monad[F[_]] extends Functor[F] {
  def unit[A](a: => A): F[A]

  def flatMap[A,B](ma: F[A])(f: A => F[B]): F[B] =
    join(map(ma)(f))

  def map[A,B](ma: F[A])(f: A => B): F[B] =
    flatMap(ma)(a => unit(f(a)))
  def map2[A,B,C](ma: F[A], mb: F[B])(f: (A, B) => C): F[C] =
    flatMap(ma)(a => map(mb)(b => f(a, b)))

  def sequence[A](lma: List[F[A]]): F[List[A]] =
    lma.foldRight(unit(List[A]()))((ma, mla) => map2(ma, mla)(_ :: _))

  def traverse[A,B](la: List[A])(f: A => F[B]): F[List[B]] =
    la.foldRight(unit(List[B]()))((a, mlb) => map2(f(a), mlb)(_ :: _))

  // For `List`, the `replicateM` function will generate a list of lists.
  // It will contain all the lists of length `n` with elements selected from the
  // input list.
  // For `Option`, it will generate either `Some` or `None` based on whether the
  // input is `Some` or `None`. The `Some` case will contain a list of length `n`
  // that repeats the element in the input `Option`.
  // The general meaning of `replicateM` is described very well by the
  // implementation `sequence(List.fill(n)(ma))`. It repeats the `ma` monadic value
  // `n` times and gathers the results in a single value, where the monad `M`
  // determines how values are actually combined.

  // Recursive version:
  def _replicateM[A](n: Int, ma: F[A]): F[List[A]] =
    if (n <= 0) unit(List[A]()) else map2(ma, _replicateM(n - 1, ma))(_ :: _)

  // Using `sequence` and the `List.fill` function of the standard library:
  def replicateM[A](n: Int, ma: F[A]): F[List[A]] =
    sequence(List.fill(n)(ma))


  def compose[A,B,C](f: A => F[B], g: B => F[C]): A => F[C] =
    a => flatMap(f(a))(g)

  def _flatMap[A,B](ma: F[A])(f: A => F[B]): F[B] =
    compose((_:Unit) => ma, f)(())

  def join[A](mma: F[F[A]]): F[A] = flatMap(mma)(ma => ma)

  def filterM[A](ms: List[A])(f: A => F[Boolean]): F[List[A]] =
    ms.foldRight(unit(List[A]()))((x,y) =>
      compose(f, (b: Boolean) => if (b) map2(unit(x),y)(_ :: _) else y)(x))
}

case class Reader[R, A](run: R => A)

object Monad {
  val genMonad = new Monad[Gen] {
    def unit[A](a: => A): Gen[A] = Gen.unit(a)
    override def flatMap[A,B](ma: Gen[A])(f: A => Gen[B]): Gen[B] =
      ma flatMap f
  }

  val parMonad = new Monad[Par] {
    def unit[A](a: => A) = Par.unit(a)
    override def flatMap[A,B](ma: Par[A])(f: A => Par[B]) = Par.flatMap(ma)(f)
  }

  def parserMonad[P[+_]](p: Parsers[P]) = new Monad[P] {
    def unit[A](a: => A) = p.succeed(a)
    override def flatMap[A,B](ma: P[A])(f: A => P[B]) = p.flatMap(ma)(f)
  }

  val optionMonad = new Monad[Option] {
    def unit[A](a: => A) = Some(a)
    override def flatMap[A,B](ma: Option[A])(f: A => Option[B]) = ma flatMap f
  }

  val streamMonad = new Monad[Stream] {
    def unit[A](a: => A) = Stream(a)
    override def flatMap[A,B](ma: Stream[A])(f: A => Stream[B]) = ma flatMap f
  }

  val listMonad = new Monad[List] {
    def unit[A](a: => A) = List(a)
    override def flatMap[A,B](ma: List[A])(f: A => List[B]) = ma flatMap f
  }

  // Since `State` is a binary type constructor, we need to partially apply it
  // with the `S` type argument. Thus, it is not just one monad, but an entire
  // family of monads, one for each type `S`. One solution is to create a class
  // `StateMonads` that accepts the `S` type argument and then has a _type member_
  // for the fully applied `State[S, A]` type inside:
  class StateMonads[S] {
    type StateS[A] = State[S, A]

    // We can then declare the monad for the `StateS` type constructor:
    val monad = new Monad[StateS] {
      def unit[A](a: => A): State[S, A] = State(s => (a, s))
      override def flatMap[A,B](st: State[S, A])(f: A => State[S, B]): State[S, B] =
        st flatMap f
    }
  }

  // But we don't have to create a full class like `StateMonads`. We can create
  // an anonymous class inline, inside parentheses, and project out its type member,
  // `lambda`:
  def stateMonad[S] = new Monad[({type lambda[x] = State[S, x]})#lambda] {
    def unit[A](a: => A): State[S, A] = State(s => (a, s))
    override def flatMap[A,B](st: State[S, A])(f: A => State[S, B]): State[S, B] =
      st flatMap f
  }

  val idMonad = new Monad[Id] {
    def unit[A](a: => A) = Id(a)
    override def flatMap[A,B](ida: Id[A])(f: A => Id[B]): Id[B] = ida flatMap f
  }

  def getState[S]: State[S,S] = State(s => (s,s))
  def setState[S](s: S): State[S,Unit] = State(_ => ((),s))

  val F = stateMonad[Int]

  def _zipWithIndex[A](as: List[A]): List[(Int,A)] =
    as.foldLeft(F.unit(List[(Int, A)]()))((acc,a) => for {
      xs <- acc
      n  <- getState
      _  <- setState(n + 1)
    } yield (n, a) :: xs).run(0)._1.reverse

  def zipWithIndex[A](as: List[A]): List[(A, Int)] =
    as.foldLeft(F.unit(List[(A, Int)]()))((acc,a) => for {
      xs <- acc
      n  <- getState
      _  <- setState(n + 1)
    } yield (a, n) :: xs).run(0)._1.reverse

  // The action of Reader's `flatMap` is to pass the `r` argument along to both the
  // outer Reader and also to the result of `f`, the inner Reader. Similar to how
  // `State` passes along a state, except that in `Reader` the "state" is read-only.

  // The meaning of `sequence` here is that if you have a list of functions, you can
  // turn it into a function that takes one argument and passes it to all the functions
  // in the list, returning a list of the results.

  // The meaning of `join` is simply to pass the same value as both arguments to a
  // binary function.

  // The meaning of `replicateM` is to apply the same function a number of times to
  // the same argument, returning a list of the results. Note that if this function
  // is _pure_, (which it should be), this can be exploited by only applying the
  // function once and replicating the result instead of calling the function many times.
  // This means the Reader monad can override replicateM to provide a very efficient
  // implementation.

  def readerMonad[R] = new Monad[({type f[x] = Reader[R,x]})#f] {
    def unit[A](a: => A): Reader[R, A] = Reader(_ => a)
    override def flatMap[A,B](st: Reader[R, A])(f: A => Reader[R, B]): Reader[R, B] =
      Reader(r => f(st.run(r)).run(r))
  }
}

case class Id[A](value: A) {
  def map[B](f: A => B): Id[B] = Id(f(value))
  def flatMap[B](f: A => Id[B]): Id[B] = f(value)
}

object Reader {
  def ask[R]: Reader[R, R] = Reader(r => r)
}




object MonadTest {

 def main(args: Array[String]): Unit = {


   val li = List("one", "two", "three", "four", "five", "six")

   val monadZipRes = Monad.zipWithIndex(li)
   val zipRes =      li.zipWithIndex
   println(monadZipRes)
   println(zipRes)

   //验证自实现的zipWithIndex与scala库自带的zipWithIndex是不是给出一致的结果
   val prop = Prop.forAll(Gen.choose(200, 301).listOf(10)) { intList =>

     //左边是scala的List数据结构自带的函数(zipWithIndex)
     intList.zipWithIndex == Monad.zipWithIndex(intList)

   }
   Prop.run(prop)



   val idMonad: Monad[Id] = Monad.idMonad
   val id4 = Id(4)
   val anotherId4 = idMonad.unit(4)
   println(id4)
   println(anotherId4)


   val replicaM = Monad.idMonad.replicateM(5, id4)
   println(replicaM)

   val id4Tuple = Monad.idMonad.flatMap(id4)((a: Int) => Monad.idMonad.map(id4)(b => (a, b)))
   println(id4Tuple)

   val anotherId4Tuple = for {
     l <- id4
     r <- id4.map(x => x)
   } yield (l, r)

   println(anotherId4Tuple)


   val idHelloMonad = for {
     a <- Id("hello ")
     b <- Id("monad")
   } yield  a + b

   println(idHelloMonad.value == "hello " + "monad")



   val s0 = Monad.F.unit(0)
  val valueAndState = for{
     a <- s0 //a 是老的状态对应的函数值
     s <- getState  //s 代表那个老的状态本身
     _ <- setState(s + 1) // 老的状态加1, 然后作为最新的状态
   } yield (a, s) // 将元组(a,s)设置为新的状态产出的函数值

   println(valueAndState.run(0))


   // 上述语句采用for推导得到一个新的状态:valueAndState,
   // 这里采用flatMap和map调用得到一个类似功能的状态: anotherValueAndState
   //valueAndState 和   anotherValueAndState 是等价的
   val anotherValueAndState = s0.flatMap(a =>  //a 是老的状态对应的函数值
     getState.flatMap(s => //s 代表那个老的状态本身
       setState(s + 1).map( // 老的状态加1, 然后作为最新的状态
         _  => (a, s) // 将元组(a,s)设置为新的状态产出的函数值
       )
     )
   )

   //将打印出: ((0,0),1),
   // 其中元组 (0,0)的第一个元素0是输入老的状态值0得到的函数值, 右边的0代表那个老的状态值。 剩下的1表示新的状态值
   //老的状态对应的函数值和老的状态本身构成的元组(也即(0, 0)将被当作新的状态的函数值
   println(anotherValueAndState.run(0))

 }

}

上述代码的运行结果是:


List((one,0), (two,1), (three,2), (four,3), (five,4), (six,5))
List((one,0), (two,1), (three,2), (four,3), (five,4), (six,5))
+ OK, passed 100 tests.
Id(4)
Id(4)
Id(List(4, 4, 4, 4, 4))
Id((4,4))
Id((4,4))
true
((0,0),1)
((0,0),1)

879675643@qq.com  lhever

.---.                                                                         
|   |   .              __.....__   .----.     .----.   __.....__              
|   | .'|          .-''         '.  \    \   /    /.-''         '.            
|   |<  |         /     .-''"'-.  `. '   '. /'   //     .-''"'-.  `. .-,.--.  
|   | | |        /     /________\   \|    |'    //     /________\   \|  .-. | 
|   | | | .'''-. |                  ||    ||    ||                  || |  | | 
|   | | |/.'''. \\    .-------------''.   `'   .'\    .-------------'| |  | | 
|   | |  /    | | \    '-.____...---. \        /  \    '-.____...---.| |  '-  
|   | | |     | |  `.             .'   \      /    `.             .' | |      
'---' | |     | |    `''-...... -'      '----'       `''-...... -'   | |      
      | '.    | '.                                                   |_|      
      '---'   '---'  
从零到一:IC Compiler II(ICC II)后端设计流程详解 本文详细解析了IC Compiler II(ICC II)后端设计流程,从环境准备到物理实现,再到布线优化与签核验证。通过实战案例和高效技巧,帮助工程师掌握ICC II工具链的应用,提升数字集成电路设计的效率和质量。 阅读详情

相关推荐

Quartus安装Altera USB-Blaster安装驱动程序出现问题(代码39)的解决办法

Quartus安装Altera USB-Blaster安装驱动程序出现问题(代码39)的解决办法

MCU_HOT的博客 1万+

【scala函数式编程】函数设计的通用结构——Monad

1. monad单子(monads) 定义:monad是一个满足associativity和identity法则的monadic组合的最小集合的实现,是对象类型的包装,用一个对象包装另一个对象,monad单子既不是trait特质也不是class类,大多数集合类型是单子,但反之不成立 补充: Functor函子——类别之间的映射,换言之,是高阶类型之间的映射,高阶类型是以类型构造器为参数的类型,举个例子,Int、List[Int]、List[T]是一阶类型,List[C[Int]]、List[C[T]

檐前潜心学种瓜 790

为Codex添加任务完成提示音:提升开发效率的实用技巧

在自动化脚本开发和模型训练过程中,实时获取任务状态反馈是提升工作效率的关键。通过Hook机制,开发者可以在代码执行的关键节点注入自定义逻辑,实现各种自动化操作。Codex的Hook系统特别适合用于任务完成提醒,其post_execution节点能准确捕获执行结束事件。技术实现上,只需简单配置TOML文件并编写音频播放脚本,就能让系统在任务完成时自动播放提示音。这种声音反馈机制尤其适用于长时间运行的批量任务和模型训练场景,实测可提升30%以上的工作效率。结合动态音效选择和跨平台兼容方案,该技巧还能扩展为桌面通

weixin_26767391的博客 550

通过Scala理解什么是Monad

什么是Monad? traitMonad[+T]{ defflatMap[U](f:(T)=>Monad[U]):Monad[U] defunit(value:B):Monad[B] } Monads 就是一个values的容器,...

778

【计算机视觉】pyrealsense2:Intel RealSense 深度相机的 Python 接口实战指南

pyrealsense2:Intel RealSense 深度相机的 Python 接口实战

weixin_43988131的博客 4353

STM32 I²C外设深度解析:时序配置、主从模式与可靠性工程

I²C是一种广泛应用于嵌入式系统的同步串行总线协议,其核心在于精确的时序控制与可靠的电气特性匹配。理解SCL/SDA信号建立/保持时间、上升下降沿约束及硬件滤波机制,是保障通信稳定的基础;STM32通过I2C_TIMINGR寄存器实现对PRESC、SCLH、SCLL、SDADEL和SCLDEL等关键参数的精细调控,直接影响tSU:DAT、tVD:DAT等标准时序合规性;该能力支撑工业级高可靠场景下的主从双向通信、时钟拉伸管理与错误恢复;本文聚焦STM32平台,结合寄存器级配置、状态机行为与实战调试经验,系统

weixin_42146230的博客 87

Scala日记——Monad的概念简介

前言 Scala一种结合面向对象(OO)和函数式编程(FP)的语言,学习函数式编程的话经常会遇到Monad(单子)这个概念,Monad是用于控制副作用的,这篇文章不介绍它是如何控制副作用,只介绍Monad涉及的概念。Haskell大神Philip Wadler说: “一个单子(Monad)说白了不过就是自函子(Endofunctor)范畴上的一个幺半群(Monoid)而已,这有什么难以理解的?...

饥渴计科极客杰铿的博客 3051

自适应IIR格型滤波器的Matlab实现

概述 在现有的众多抑制窄带干扰的信号处理手段中,时域自适应陷波干扰抑制技术具有实现简单、抗干扰性能好等优点。IIR陷波器按照结构可以分为直接型和格型两种。相比自适应直接型IIR陷波器,自适应格型IIR陷波器不仅可以准确地控制滤波器的陷波频率,也可以准确地调整陷波器的带宽。 传递函数 二阶自适应IIR格型陷波器的传递函数H(z)为: 其中α与陷波带宽有关,β与陷波频率有关;对应的结构如下图所示: Matlab算法实现 ...

剑藏锋的博客 2803

Scala和范畴论 -- 对Monad的一点认识

背景 所有一切的开始都是因为这句话:一个单子(Monad)说白了不过就是自函子范畴上的一个幺半群而已,有什么难以理解的。第一次看到这句话是在这篇文章:程序语言简史(伪)。这句话出自Haskell大神Philip Wadler,也是他提议把Monad引入Haskell。Monad是编程领域比较难理解的概念之一,大部分人都是闻"虎"而色变,更...

weixin_34122604的博客 300

深入浅出:利用NXP S32K3xx的HSE模块实现OTA双分区(AB Swap)与安全回滚

本文深入解析NXP S32K3xx HSE模块在汽车电子OTA双分区架构中的工程实践,详细介绍了HSE模块如何通过AB Swap双分区机制实现固件安全升级与毫秒级回滚。内容涵盖内存重映射硬件原理、分区切换异常处理及寄存器级诊断方法,为开发高可靠嵌入式系统提供实战指导。

weixin_30919429的博客 799

手把手教你搭建离线语音助手:FunASR+DeepSeek+TTS保姆级教程

本文详细介绍了如何利用FunASR、DeepSeek和TTS技术搭建离线语音助手系统。从环境配置、模型部署到唤醒词检测优化、语音识别与语义理解联调,再到语音合成与系统集成,提供全链路实战教程。特别适合智能家居控制、企业内部知识问答等需要数据隔离的场景,实现高响应、低延迟的离线语音交互体验。

weixin_30316097的博客 476

【Scala高手私藏笔记】:彻底搞懂Monad模式的3种实现路径与应用场景

掌握Scala函数式编程中的Monad模式,本文深入解析3种实现路径及其在异步处理、错误控制与状态管理中的应用。清晰拆解核心原理与实战技巧,提升代码抽象能力,值得收藏。

ByteGlow的博客 860

解决 maven编译项目-Fatal error compiling: 无效的目标发行版: 21 -> [Help 1]

惊奇的发现,maven没有用环境变量中设置好的JAVA_HOME目录,至此发现错误原因,原来执行java -version默认使用系统环境变量JAVA_HOME,而maven优先使用了windows的用户变量JAVA_HOME(这里之前忘记修改,仍然指向java8路径),修改用户变量JAVA_HOME指向java21或删除该用户变量JAVA_HOME(如无它用)后即可。打开maven包所在的目录,在maven的配置文件 mvn.cmd 文件中,设置java_home的目录。

litlit023的专栏 1801

【活动回顾】2023 年 1 月 Scala Meetup

第八期 Scala Meetup 于上周六顺利结束,三位 Scala 资深使用者与 2000+ 在线用户分享了三大话题:Tubi 的 gRPC 演进之路、Scala 与函数式编程、交互式笔记本中的 Scala。同时,应粉丝提问,大家也对“ Scala 入门和进阶路径、Akka 在分布式场景中的应用”等备受关注的问题进行了讨论。

weixin_49193714的博客 191

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Scala自定义Monad实战:从理论到应用的完整指南

1. 引言:为什么需要自定义Monad?2. Monad的本质回顾2.1 Monad的数学定义2.2 Monad三大定律2.3 Monad的核心思想3. 自定义Monad的基础实现3.1 最简单的Monad:Identity Monad3.2 带日志的Monad:Writer Monad3.3 带状态的Monad:State Monad4. 实际应用场景一:工作流引擎4.1 业务流程工作流Monad4.2 工作流执行流程5. 实际应用场景二:交易处理系统5.1 金融交易Monad。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 2182

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

函数式编程的链式魔法:深入理解Scala Monad及其链式操作

pure(也称为return或unit):将普通值放入Monad上下文中flatMap(也称为bind或>>=):从Monad上下文中取出值应用函数,并保持上下文def pure[A](a: A): F[A] // 将值放入上下文def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B] // 核心组合操作// 派生方法// 提供隐式实例// 一个带日志的Monad// 隐式Monad实例// 使用Logger Monadx"))x。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 4366

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

揭秘Scala中的Monad

In my previous post I mentioned how I decided to write about variance despite the fact that there are already several dozen articles about the topic. This is a similar situation. I am aware that this ...

525

Monad in Scala

Scala有很强的类型系统。加上一些隐式规则,我们可以在scala里模拟haskell的monad。 先从haskell的monad type class开始: class Monad M where ret :: a -> M a bind :: M a -> (b -> M b) -> M b 这里M是type class的参数。它是一个高阶类...

a882990123的博客 163

genshin-wish-export 原神抽卡记录导出指南

想回看某个五星是在哪个卡池出的、抽了几次才出货,游戏内只给流水,不给统计。genshin-wish-export 把完整抽卡历史导出成 Excel,各卡池五星概率、平均出货次数都能精确到每一次,帮你省掉手动记档的功夫。 ## 它是怎么工作的 - **authKey 从哪来**:工具读取游戏日志或启动本地代理。你在游戏里打开祈愿历史记录时,它就能拿到访问祈愿 API 所需的 authKey。 -

gitblog_00462的博客 304

fpinscala 第 11 章习题 17:手写 `Id` Monad——最简单的恒等 Monad 实现与源码验证

本文聚焦《Functional Programming in Scala》配套仓库 fpinscala 中第 11 章(monads)习题 17 的解答——实现 `Id` 数据类型及其 Monad 实例。`Id`(Identity,恒等)包装器是所有 Monad 中最简单的一种:它不携带任何额外效果,`flatMap` 就是直接应用函数。文章将以 [answerkey/monads/17.answ

gitblog_01019的博客 170

fetchLater() 全会话分析实战:modern-web-guidance 中的可靠遥测采集指南

在用户关闭标签页或离开页面的瞬间,如何保证分析数据、Core Web Vitals、错误日志和遥测不丢失? `modern-web-guidance` 仓库中的全会话分析指南给出的答案是 `fetchLater()`:把数据交给浏览器排队,由浏览器在页面生命周期结束时可靠投递。本文以 [full-session-analytics/guide.md](https://link.gitcode.co

gitblog_00606的博客 468

【完全免费】免安装开箱即用:用 Firefox 52.0.2 渗透便携版三分钟搭好随身渗透测试环境

换台笔记本就要重装一套插件?Firefox 52.0.2 渗透便携版值得看一眼。它是基于 Firefox 52.0.2 内核的便携浏览器包,预装三个方向的渗透测试插件,解压后双击就能干活。 ## 换电脑就要重新配插件?受限环境里做渗透测试的真实处境 上次去现场做测试,借了台客户的笔记本,环境配了快一小时:浏览器版本太新,老插件不兼容;版本太旧,系统又不让装。最后只好从包里翻出一个 U 盘。

gitblog_00322的博客 163

Citra 3DS模拟器实用上手指南:配置快查、代码拉取与首款游戏加载

想在电脑上玩任天堂 3DS 游戏,主流的开源自带方案是 Citra——一款 3DS 模拟器,可在 Windows、macOS、Linux 上运行 3DS 游戏,并支持超出原机规格的高清画面输出。下文按实际动手的顺序展开:先确认机器是否够格,再拉取代码,接着完成首跑设置、加载第一款游戏,最后处理卡顿排查与进阶玩法。 ## 动手前先过一遍配置快查表 Citra 对硬件有一定门槛,尤其是 CPU 必

gitblog_00070的博客 357

百度网盘macOS限速插件:100KB/s到7MB/s

假设你正在 macOS 百度网盘里下载一个 9GB 的文件,速度停在 100 KB/s、剩余时间超过 1 天,先别急着怀疑网络,问题多半出在客户端本地的限速策略上。开源插件 BaiduNetdiskPlugin-macOS 会往 2.2.2 版客户端里注入一个动态库,把本地限速直接移除,截图里同样的任务从 100 KB/s 跑到 7.08 MB/s,剩余时间从"超过 1 天"变成 21 分钟左右。

gitblog_00214的博客 202

Eff扩展效果框架完全入门:为什么Scala函数式编程该告别Monad Transformer?

Eff 是 Atnos 社区推出的**扩展效果(Extensible Effects)框架**,基于 "free-er" 单子实现,为 Scala 函数式编程提供了一种比 Monad Transformer 更灵活、可组合的"效果栈"方案。如果你被层层嵌套的 Transformer 类型折磨过,这篇入门指南会用最短的篇幅帮你搞懂 Eff 的核心思想、内置效果和源码结构,快速完成技术选型。 ##

gitblog_00148的博客 332

函数式Scala编程:Effective Scala中的Option、flatMap与惰性求值

函数式编程在现代软件开发中扮演着越来越重要的角色,而Scala作为一门融合了面向对象和函数式编程范式的语言,为开发者提供了强大的工具集。Twitter的Effective Scala指南作为Scala编程的权威参考,系统介绍了Option、flatMap与惰性求值等核心概念,帮助开发者编写更安全、高效的函数式代码。本文将深入解析这些关键技术,带你掌握函数式Scala编程的实用技巧。 ## 如何使

gitblog_00096的博客 923
上一篇: Monoid在Scala中的应用笔记
下一篇: 可应用和可遍历函子(Applicative And Traversable Functor)在Scala中的应用笔记
lhever_
博客等级 码龄14年 213粉丝 130原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值