当前位置: 首页 > news >正文

Kotlin基础——Typeclass

高阶类型

如在Iterable新增泛型方法时

interface Iterable<T> {fun filter(p: (T) -> Boolean): Iterable<T>fun remove(p: (T) -> Boolean): Iterable<T> = filter { x -> !p(x) }
}

对应的List、Set实现上述方法时仍需要返回具体的类型

interface List<T> : Iterable<T> {fun filter(p: (T) -> Boolean): List<T>fun remove(p: (T) -> Boolean): List<T> = filter { x -> !p(x) }
}interface Set<T> : Iterable<T> {fun filter(p: (T) -> Boolean): Set<T>fun remove(p: (T) -> Boolean): Set<T> = filter { x -> !p(x) }
}

使用高阶类型可以解决上述问题,高阶类型指的是用类型构造新类型,Kotlin可以通过扩展实现高阶类型(下面例子都是根据这个来实现)

interface Kind<out F, out A>sealed class List<out A> : Kind<List.K, A> {object K
}inline fun <A> Kind<List.K, A>.unwrap(): List<A> = this as List<A>object Nil : List<Nothing>()
data class Cons<A>(val head: A, val tail: List<A>) : List<A>()
  • Kind<out F, out A>表示类型构造器F应用类型参数A产生的新类型,F实际上不能携带类型参数
  • List.K是List的高阶类型,也就是说传入不同的A,根据List.K会有不同类型
  • unwrap()将Kind<List.K, A>类型转为List<A>进行操作
  • Nil为空列表用作尾部,Cons由元素head和及其指向tail构成的链表

Functor

Functor的map():通过f()方法将Kind<F, A>类型转为Kind<F, B>类型

interface Functor<F> {fun <A, B> Kind<F, A>.map(f: (A) -> B): Kind<F, B>
}object ListFunctor : Functor<List.K> {override fun <A, B> Kind<List.K, A>.map(f: (A) -> B): Kind<List.K, B> {return when (this) {is Cons -> {val t = (this.tail.map(f)).unwrap()Cons<B>(f(this.head), t)}else -> Nil}}
}

使用方法如下,将Con<Int>转为了Con<String>

val cons: Cons<Int> = Cons(1, Nil)
println(cons.head::class)
println(cons.tail)
ListFunctor.run {val cons2: Cons<String> = cons.map { it.toString() } as Cons<String>println(cons2.head::class)println(cons2.tail)
}

打印如下

class kotlin.Int
com.demo.demo1.Nil@5361555
class kotlin.String
com.demo.demo1.Nil@5361555

Eq和ListEq

Eq

Eq根据传入的类型参数,对其制定比较规则

interface Eq<F> {fun F.eq(that: F): Boolean
}
object IntEq : Eq<Int> {override fun Int.eq(that: Int): Boolean {return this == that}
}

如上,对于Int,判断值是否相等,使用方法如下

IntEq.run {val a = 1println(a.eq(1))println(a.eq(2))
}

打印如下

true
false

ListEq

ListEq可根据指定类型参数的比较规则,实现对两个List比较

abstract class ListEq<A>(val a: Eq<A>) : Eq<Kind<List.K, A>> {override fun Kind<List.K, A>.eq(that: Kind<List.K, A>): Boolean {val curr = thisreturn if (curr is Cons && that is Cons) {val headEq = a.run {curr.head.eq(that.head)}if (headEq) curr.tail.eq(that.tail) else false} else curr is Nil && that is Nil}
}
object IntListEq : ListEq<Int>(IntEq)

如上,实现IntListEq,使用方法如下

IntListEq.run {val a = Cons(1, Cons(2, Nil))val b = Cons(1, Cons(2, Nil))val c = Cons(1, Nil)println(a.eq(b))println(a.eq(c))
}

打印如下

true
false

show和Foldable

Show

show根据传入的类型参数,对其制定输出规则

interface Show<F> {fun F.show(): String
}
class Book(val name: String)
object BookShow : Show<Book> {override fun Book.show(): String = this.name
}

如上,对于Book,输出name属性,调用方法如下

BookShow.run {println(Book("Dive into Kotlin").show())
}

打印如下

Dive into Kotlin

Foldable

Foldable根据传入的类型参数,对其进行拼接(不太能理解这个fold的实现。。。)

interface Foldable<F> {fun <A, B> Kind<F, A>.fold(init: B): ((B, A) -> B) -> B
}
object ListFoldable : Foldable<List.K> {override fun <A, B> Kind<List.K, A>.fold(init: B): ((B, A) -> B) -> B = { f ->fun fold0(l: List<A>, v: B): B {return when (l) {is Cons -> {fold0(l.tail, f(v, l.head))}else -> v}}fold0(this.unwrap(), init)}
}

ListShow

abstract class ListShow<A>(val a: Show<A>) : Show<Kind<List.K, A>> {override fun Kind<List.K, A>.show(): String {val fa = thisreturn "[" + ListFoldable.run {fa.fold(listOf<String>())({ r, i ->r + a.run { i.show() }}).joinToString() + "]"}}
}
object BookListShow : ListShow<Book>(BookShow)

调用方法如下

BookListShow.run {println(Cons(Book("Dive into Kotlin"),Cons(Book("Thinking in Java"), Nil)).show())
}

打印如下

[Dive into Kotlin, Thinking in Java]

Monoid

Monoid满足结合律和同一律

interface Monoid<A> {fun zero(): Afun A.append(b: A): A
}

如对于字符串Monoid

  • 结合律:(“A”+“B”)+“C” == “A”+(“B”+“C”)
  • 同一律:“A”+“” == “A”
object StringConcatMonoid : Monoid<String> {override fun zero(): String = ""override fun String.append(b: String): String = this + b
}
fun <A> List<A>.sum(ma: Monoid<A>): A {val fa = thisreturn ListFoldable.run {fa.fold(ma.zero())({ s, i ->ma.run {s.append(i)}})}
}

使用方式如下

println(Cons("Dive ",Cons("into ",Cons("Kotlin", Nil))).sum(StringConcatMonoid)
)

打印如下

Dive into Kotlin

Monad

Monad包含了最小的原始操作集合pure()和flatMap(),通过这两个组合,我们可以实现更复杂的数据转换操作

interface Monad<F> {fun <A> pure(a: A): Kind<F, A>fun <A, B> Kind<F, A>.flatMap(f: (A) -> Kind<F, B>): Kind<F, B>
}

如下实现ListMonad

object ListMonad : Monad<List.K> {private fun <A> append(fa: Kind<List.K, A>, fb: Kind<List.K, A>): Kind<List.K, A> {return if (fa is Cons) {Cons(fa.head, append(fa.tail, fb).unwrap())} else {fb}}override fun <A> pure(a: A): Kind<List.K, A> {return Cons(a, Nil)}override fun <A, B> Kind<List.K, A>.flatMap(f: (A) -> Kind<List.K, B>): Kind<List.K, B> {val fa = thisval empty: Kind<List.K, B> = Nilreturn ListFoldable.run {fa.fold(empty)({ r, l ->append(r, f(l))})}}
}

Applicative

数学上3中代数结构关系如下Functor -> Applicative -> Monad

interface Functor<F> {fun <A, B> Kind<F, A>.map(f: (A) -> B): Kind<F, B>
}interface Applicative<F> : Functor<F> {fun <A> pure(a: A): Kind<F, A>fun <A, B> Kind<F, A>.ap(f: Kind<F, (A) -> B>): Kind<F, B>override fun <A, B> Kind<F, A>.map(f: (A) -> B): Kind<F, B> {return ap(pure(f))}
}interface Monad<F> : Applicative<F> {fun <A, B> Kind<F, A>.flatMap(f: (A) -> Kind<F, B>): Kind<F, B>override fun <A, B> Kind<F, A>.ap(f: Kind<F, (A) -> B>): Kind<F, B> {return f.flatMap { fn ->this.flatMap { a ->pure(fn(a))}}}
}

Option和OptionT

Kotlin中没有checked Exception,而是使用类型代替异常处理错误

Either和EitherT

相关文章:

Kotlin基础——Typeclass

高阶类型 如在Iterable新增泛型方法时 interface Iterable<T> {fun filter(p: (T) -> Boolean): Iterable<T>fun remove(p: (T) -> Boolean): Iterable<T> filter { x -> !p(x) } }对应的List、Set实现上述方法时仍需要返回具体的类型 interfac…...

DC-DC 高压降压、非隔离AC-DC、提供强大的动力,选择优质电源芯片-(昱灿)

畅享长续航&#xff0c;尽在我们的充电芯片&#xff01; 无论是手机、平板还是智能设备&#xff0c;长时间使用后电量不足总是令人头疼。然而&#xff0c;我们的充电芯片将为您带来全新的充电体验&#xff01;采用先进的技术&#xff0c;我们的充电芯片能够提供快速而稳定的充电…...

GPT-4o的视觉识别能力,将绕过所有登陆的图形验证码

知识星球&#x1f517;除了包含技术干货&#xff1a;《Java代码审计》《Web安全》《应急响应》《护网资料库》《网安面试指南》还包含了安全中常见的售前护网案例、售前方案、ppt等&#xff0c;同时也有面向学生的网络安全面试、护网面试等。 我们来看一下市面上常见的图形验证…...

【LinuxC语言】进程间的通信——管道

文章目录 前言不同进程间通信的方式管道匿名管道和命名管道半双工与全双工管道相关函数创建管道总结前言 在Linux操作系统中,进程是执行中的程序的实例。每个进程都有自己的地址空间,数据栈以及其他用于跟踪进程执行的辅助数据。操作系统管理这些进程,并通过调度算法来分享…...

CompletableFuture 基本用法

一、 CompletableFuture简介 CompletableFuture 是 Java 8 引入的一个功能强大的类&#xff0c;用于异步编程和并发处理。它提供了丰富的 API 来处理异步任务的结果&#xff0c;支持函数式编程风格&#xff0c;并允许通过链式调用组合多个异步操作。 二、CompletableFuture中…...

网页如何发布到服务器上

将网页发布到服务器上的过程涉及多个步骤&#xff0c;包括准备阶段、选择托管提供商、发布网站等。12 准备阶段&#xff1a; 确保在本地开发环境中对网站进行了充分的测试&#xff0c;包括功能测试、性能测试和安全测试。 检查Web.config文件&#xff0c;确保所有的配置设置…...

Jenkins简要说明

Jenkins 是一个开源的持续集成和持续部署&#xff08;CI/CD&#xff09;工具&#xff0c;广泛用于自动化软件开发过程中的构建、测试和部署等任务。它是基于Java开发的&#xff0c;因此可以在任何支持Java的平台上运行&#xff0c;并且能够与各种操作系统、开发工具和插件无缝集…...

C# 比较基础知识:最佳实践和技巧

以下是一些在 C# 中进行比较的技巧和窍门的概述。 1. 比较原始类型 对于原始类型&#xff08;int、double、char 等&#xff09;&#xff0c;可以使用标准比较运算符。 int a 5; int b 10; bool isEqual (a b); // false bool isGreater (a > b); // false bool is…...

Ansible 自动化运维实践

随着 IT 基础设施的复杂性不断增加&#xff0c;手动运维已无法满足现代企业对高效、可靠的 IT 运维需求。Ansible 作为一款开源的自动化运维工具&#xff0c;通过简洁易用的 YAML 语法和无代理&#xff08;agentless&#xff09;架构&#xff0c;极大简化了系统配置管理、应用部…...

红队攻防渗透技术实战流程:中间件安全:IISNGINXAPACHETOMCAT

红队攻防渗透实战 1. 中间件安全1.1 中间件-IIS-短文件&解析&蓝屏等1.2 中间件-Nginx-文件解析&命令执行等1.2.1 后缀解析 文件名解析1.2.2 cve_2021_23017 无EXP有POC1.2.3 cve_2017_7529 意义不大1.3 中间件-Apache-RCE&目录遍历&文件解析等1.3.1 cve_20…...

如何卸载宝塔面板?

宝塔官方有提供宝塔面板的卸载命令&#xff0c;使用这个卸载命令&#xff0c;我们就能将宝塔面板卸载掉。 这里有一点需要注意的&#xff0c;如果卸载宝塔面板的同时&#xff0c;也希望将 Nginx、MySQL、PHP 等组件卸载掉&#xff0c;那么我们应该先在宝塔面板里面卸载掉以上软…...

python入门基础知识(错误和异常)

本文部分内容来自菜鸟教程Python 基础教程 | 菜鸟教程 (runoob.com) 本人负责概括总结代码实现。 以此达到快速复习目的 目录 语法错误 异常 异常处理 try/except try/except...else try-finally 语句 抛出异常 用户自定义异常 内置异常类型 常见的标准异常类型 语法…...

迈巴赫S480升级增强现实AR抬头显示hud比普通抬头显示HUD更好用吗

增强AR实景抬头显示HUD&#xff08;Augmented Reality Head-Up Display&#xff09;是一种更高级的驾驶辅助技术&#xff0c;相比于普通抬头显示HUD&#xff0c;它提供了更丰富、更具沉浸感的驾驶体验。以下是它比普通抬头显示HUD多的一些功能&#xff1a; • 信息呈现方式&am…...

vivado、vitis2022安装及其注意事项(省时、省空间)

1、下载 AMD官网-资源与支持-vivado ML开发者工具&#xff0c;或者vitis平台&#xff0c; 下载的时候有个官网推荐web安装&#xff0c;亲测这个耗时非常久&#xff0c;不建议使用&#xff0c;还是直接下载89G的安装包快。 注意&#xff1a;安装vitis平台会默认安装vivado&…...

【自动驾驶】ROS小车系统

文章目录 小车组成轮式运动底盘的组成轮式运动底盘的分类轮式机器人的控制方式感知传感器ROS决策主控ROS介绍ROS的坐标系ROS的单位机器人电气连接变压模块运动底盘的电气连接ROS主控与传感器的电气连接ROS主控和STM32控制器两种控制器的功能运动底盘基本组成电池电机控制器与驱…...

mysql学习——多表查询

多表查询 内连接外连接自连接自连接查询联合查询 子查询 学习黑马MySQL课程&#xff0c;记录笔记&#xff0c;用于复习。 添加外键 alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id);多表查询 select * from emp , dept where emp…...

【Gradio】如何设置 Gradio 数据框的样式

简介 数据可视化是数据分析和机器学习的关键方面。Gradio DataFrame 组件是一种流行的方式&#xff0c;在网络应用程序中显示表格数据&#xff08;特别是以 pandas DataFrame 对象的形式&#xff09;。 本文将探讨 Gradio 的最新增强功能&#xff0c;这些功能允许用户整合 pand…...

【ThreeJS】Threejs +Vue3 开发基础

目前流行的前端3D框架以以Three.js、Babylon.js、A-Frame和ThingJS为例&#xff1a; 1.Three.js 功能&#xff1a; 提供了大量的3D功能&#xff0c;包括基本几何形状、材质、灯光、动画、特效等。 易用性&#xff1a; 功能强大且易于使用&#xff0c;抽象了复杂的底层细节&…...

cocos 如何使用九宫格图片,以及在微信小程序上失效。

1.在图片下方&#xff0c;点击edit。 2.拖动线条&#xff0c;使四角不被拉伸。 3.使用。 其他 在微信小程序上失效&#xff0c;需要将packable合图功能取消掉。...

Spring企业开发核心框架

一、框架前言 1、总体技术体系 单一架构 一个项目&#xff0c;一个工程&#xff0c;导出为一个war包&#xff0c;在一个Tomcat上运行。也叫all in one. 单一架构&#xff0c;项目主要应用技术框架为&#xff1a;Spring&#xff0c;SpringMVC&#xff0c;Mybatis等 分布式架构…...

s2-pro开源TTS模型深度解析:Fish Audio专业级架构与训练逻辑

s2-pro开源TTS模型深度解析&#xff1a;Fish Audio专业级架构与训练逻辑 1. 专业级语音合成模型概述 s2-pro是Fish Audio团队开源的一款专业级文本转语音(TTS)模型镜像&#xff0c;代表了当前开源语音合成技术的先进水平。与普通TTS系统不同&#xff0c;s2-pro不仅支持常规的…...

BsMax:让3D艺术家无缝切换Blender的专业级工具集

BsMax&#xff1a;让3D艺术家无缝切换Blender的专业级工具集 【免费下载链接】BsMax BsMax Blender Addon (UI simulator/ Modeling/ Rigg & Animation/ Render Tools and ... 项目地址: https://gitcode.com/gh_mirrors/bs/BsMax 你是否曾经因为Blender的操作习惯与…...

Topit:让Mac窗口像便利贴一样随手可贴,你的多任务效率神器

Topit&#xff1a;让Mac窗口像便利贴一样随手可贴&#xff0c;你的多任务效率神器 【免费下载链接】Topit Pin any window to the top of your screen / 在Mac上将你的任何窗口强制置顶 项目地址: https://gitcode.com/gh_mirrors/to/Topit 还在为Mac上频繁切换窗口而打…...

从零到精通的Android Kotlin实战学习旅程:50个项目带你掌握移动开发核心技能

从零到精通的Android Kotlin实战学习旅程&#xff1a;50个项目带你掌握移动开发核心技能 【免费下载链接】50-android-kotlin-projects-in-100-days My everyday Android practice demos with Kotlin in 100 days. 项目地址: https://gitcode.com/gh_mirrors/50/50-android-k…...

RT-DETR Decoder里的‘去噪’与‘软标签’:加速训练收敛的实战技巧

RT-DETR Decoder里的‘去噪’与‘软标签’&#xff1a;加速训练收敛的实战技巧 在目标检测领域&#xff0c;RT-DETR凭借其出色的实时性能和检测精度&#xff0c;正逐渐成为工业界和学术界的热门选择。然而&#xff0c;许多实践者在模型训练过程中常常遇到收敛速度慢、训练不稳定…...

终极指南:3步永久解密科学文库PDF文档,告别7天访问限制

终极指南&#xff1a;3步永久解密科学文库PDF文档&#xff0c;告别7天访问限制 【免费下载链接】ScienceDecrypting 破解CAJViewer带有效期的文档&#xff0c;支持破解科学文库、标准全文数据库下载的文档。无损破解&#xff0c;保留文字和目录&#xff0c;解除有效期限制。 …...

[具身智能-218]:针对不同编程语言和应用场景,AI自动编程擅长与不擅长之处?

AI自动编程的能力在不同编程语言和应用场景下表现出显著差异。选择合适组合&#xff0c;能让AI成为强大的“加速器”&#xff0c;反之则可能带来风险。 核心原则是&#xff1a;AI对主流语言和标准化任务的支持最好&#xff0c;而在处理底层、高性能或复杂业务逻辑时则需要人工…...

Qwen3.6-Plus 全面解析:性能提升、API 接入与 Claude Code 实战配置

点击下方“JavaEdge”&#xff0c;选择“设为星标”第一时间关注技术干货&#xff01;本文已收录在Github&#xff0c;关注我&#xff0c;紧跟本系列专栏文章&#xff0c;咱们下篇再续&#xff01;&#x1f680; 魔都架构师 | 全网30W技术追随者&#x1f527; 大厂分布式系统/数…...

我为什么放弃商用OCR,自己写了个发票助手?

作为一个常年和发票打交道的互联网人&#xff0c;我对市面上的发票识别工具早就忍无可忍了。 每次报销季&#xff0c;手机里的发票照片堆得像小山&#xff0c;用某付费OCR工具识别时&#xff0c;看着屏幕上“正在上传云端处理”的提示&#xff0c;总觉得心里发毛——这些包含公…...

3分钟搞定AdGuard浏览器扩展安装:终极广告拦截与隐私保护指南

3分钟搞定AdGuard浏览器扩展安装&#xff1a;终极广告拦截与隐私保护指南 【免费下载链接】AdguardBrowserExtension AdGuard browser extension 项目地址: https://gitcode.com/gh_mirrors/ad/AdguardBrowserExtension AdGuard浏览器扩展是一款功能强大的开源广告拦截工…...