/tmp/duangsuse.sock
23 subscribers
303 photos
3 videos
92 files
337 links
从 duangsuse::Echo (@dsuse) 跟进出来的分支,将在作者恢复原帐号访问的时候合并删除。
Download Telegram
添加的特性:

Fucn helper:
添加 static Func?<...> into(Func?<...>) 方法
可以这么用:

Funv2<String, User> $ = Func.into(users::put);

添加 flip3 函数,重命名 curryflip 的名字为带数字的版本
curry 作为 default 实现

var $ = Func.flip3$1(Func.into(db::getFromDictOrDefault)).curry1("user").curry1("阿强")
$.apply("阿珍");

为 Func3 和 Funv3 、Func2, Funv2 添加 curry2 函数
让 Func2 和 Funv2 继承 java.util.function.Function
让 Func1 和 Funv1 继承 java.util.function.Consumer
让 Func0 和 Funv0 继承 java.lang.Runnable

其他 Func 接口的 SAM 方法重命名为 invoke

ADT 包的 Data 类我希望能加点反射 Annotation 元数据使用
争取能做到低开销和快速原型都 OK

class User extends Data {
String id, name, nick
bio;
int age;
Date created, lastOnline;
}

然后应该不需要任何其他东西来完成 equals, toString, hashCode
感觉自己好菜... IDE 快捷键多久也记不住,重构也记不了几个,
Git CLI 的配置不会编辑、vi 和 emacs 不会用
就连写个 iterator 都花了我半天时间....
打字也很慢... dvork 键盘布局也不会用
d ua ng suse 陷入了无休止的重复之中...
/tmp/duangsuse.sock
添加的特性: Fucn helper: 添加 static Func?<...> into(Func?<...>) 方法 可以这么用: Funv2<String, User> $ = Func.into(users::put); 添加 flip3 函数,重命名 curry 和 flip 的名字为带数字的版本 将 curry 作为 default 实现 var $ = Func.flip3$1(Func.into(db::getFromDictOrDefault)).curry1("user").curry1("阿强")…
最后实际上:我弄错了 FuncX 的含义

Func2 是接受两个参数的函数,所以实际上它不入流,是我的扩展

Func1<R, I0> 是 Function<I0, R> 的子类型
Funv<I0> 同时是 Consumer<I0> 的子类型

Func0<R> 是 Supplier<R> 的子类型
Funv0 是 Runnable
其实这种事情应该让编译器干更好(
其实我有点想放弃了,它的确是有点花时间... 虽然这对我来说也是一种不错的锻炼

过程中,我要忍受自己不怎么样的击键速度和 gnome-break-timer 每隔 6 分钟一次的休息提示...

虽然这的确强化了我对 Java 的认知,弥补了之前知识和理解上的缺失(比如 @interface

温故而知新,是非常好的学习方法。

... 其实我也是想早点开发 *** 实际应用的,可是... 好像写测试还要很久

Promise-Java 本来只是作为一个 essay 来写的,因为早期创建项目的困难(比如我不熟悉 Maven,对 XML 的感觉很差)我几乎每个项目都只是能按照语言内部的模块化系统划分而已,而且经常有挂羊头𧹒狗肉的情况(经常多写很多本来在其他模块里的代码)

Promise 写的时候要用一点 functional programming 里常用的数据和操作,于是我就写了 fuctional 包,后来又加上了一个 functional.adt 的包,添加了越来越多的抽象和实现...

依照目前的情况来看,虽然我编程不再会出现语法和类型错误了,但程序逻辑依然可能因为种种原因(比如,零基数组的索引计算、某些 API 的输入输出不是很理解)出现错误

目前根据测试,已经至少出现了十次以上的错误(虽然都得到了妥善解决)

这些东西是非得写测试不可的(要不然我不能保证他们的正确性,其次,写的时候我会稍微开心一点)...

我打算尽力克服... 毕竟这些都是要用的东西(真香!)
之前已经真香预警过了,我打算将这些部分不确定正确性的破烂的代码留作日后复制使用。(thinking) 好耶,(虽然不算泛型擦除以及泛型本身不耗多少空间),居然只有 56K!可以随便用里面的函数式编程风格了!(不准吐槽我为什么没有用一些 constraint 库,也没写太多文档) 没有什么是永恒的,何况这是一个免费的项目。我抛弃它了,我渣男(跑
艹,劳资 TMD 才想起来,我还以为自己做了很了不起的『优化』呢(这个思路很简单,就是 exception 要比正常返回多花时间),可是我就没有看出来这才是真正的优化... 为什么要避开常用的思路去 exception,其实就是『乐观(optimistic)』的优化思路啊!既然翻译本来就几乎不可能缺失,我为什么要每次去检查... 以后这个脑子还是要灵活一点 😭
static String $$(final String key) {
if (RESOURCE_BUNDLE.containsKey(key))
return RESOURCE_BUNDLE.getString(key);
return '!' + key + '!'; }

— eclipse 自动生成的 真·大佬方案

static String $$(final String key) {
try {
return RESOURCE_BUNDLE.getString(key); }
catch (MissingResourceException ignored) { return '!' + key + '!'; }}
/tmp/duangsuse.sock
吃上了 Eclipse Java(
🙈 其实这里第一个例子 #Java #Androidassert 是错的... 大家看着理解就好了,我的意思主要关于『等价』
具体情况是下面语言实现的层面考虑的

Button.OnClickListener exitApplication = ($) -> { ctx.finish(); };
assert exitApplication == new Button.OnClickListener() {
@Override void onClick(View _) { ctx.finish(); }
};

另外原来的 this 有个遮盖的问题,Kotlin 语法可以所以能用 this@scope 解决,Java 就没有办法惹
/tmp/duangsuse.sock
那么现在先开始讲『下面的事情』 🤔
先说一个无聊的做铺垫:

1. 走路的分段速度和音频流处理的窗口
(作者对信号处理和物理学都是外行,如果有发现错误请务必指出)

关于速度的计算,有一个问题,就是现实中我们无论如何也无法得知确切的瞬时速度。

所以就有了按时间段计算:路程/时间 = 速度
一般情况下都认为路程和时间都是连续的(无法分割为可枚举的一堆值阶或者集合什么的)
只要取到了一定的精度,实际上就可以认为是『瞬时的』速度。

信号处理也是一个道理,针对某一种需要一定量信号的算法,也可以指定一个比较大的窗口大小,执行实际处理,而不需要针对一个点发呆或者干脆认为『现实世界的信号是连续的,无法实现』一样

对于实时的网络流也是一样,可以裁切成片段发送(反正本来就是片段... 音频有每秒采样视频有帧)

2. Monad, Functor 和 flatMap

Functor 是什么呢?就是可以 map 的东西(当然这个冰封哥早期讲过,不过没有细说)

首先世界是这个样子的:
有一种东西:对象(object)
有一种操作:态射(morphism)
对象是节点(node)、态射是边(edge),组成了一张范畴的图(graph)

对象是 a;态射是 a ~> a
这里的 a 可以理解为某种类型(

下面的是 Haskell 写的代码,当然很简单啦(否认

x :: TYPE 前面的是一个变量,后面的是它的类型
t -> r 这是 Haskell 的函数类型,它接受一个 t 类型返回一个 r 类型
这里 t, r 都是 Haskell 的类型变量,而大写的类型则是 Haskell 真正的类型
t 也可以是函数类型,比如 p -> q(左递归 Left recursive)
(a, b) 这是 Haskell 的元组,它的 fst :: (a, b) -> aa, sndb

curry :: ((a, b) -> c) -> a -> b -> c
检验:描述一下它的类型

id :: a -> a
id x = x

然后这是类型啊,编程也很简单,比如有 add1 :: Int -> Intmultiply :: Int -> Int -> Int
实现了 (x+1) 和 (x*y) 就可以定义 times10p1 :: Int -> Int
times10p1 x = add1 (multiply 10 x)
当然有魔法的版本,Haskell 的语法很灵活
times10p1 = add1 . (multiply 10)
这就是说:(add1) 和 (multiply 10) 都是 Int -> Int (有 currying)
(currying 就是)
m10 = multiply 10
m10 10 == 100
然后可以 (.) :: (Int -> Int) -> (Int -> Int) -> (Int -> Int)
拿到 times10p1 这样子

times10p1 = add1 . (multiply 10)
where
add1 = (+1)
multiply = (*)

函数式编程主张使用可拆分的定义组织你的程序,基本元素越简单越好

Haskell 的基础 Lambda 演算就只有三种项:
x: variable
(λx. x): abstraction
(f x): application

当然还有一个上下文 Γ(Gamma) 也就是 Haskell 里的 where... / let...in
两种基本操作:β(beta)-reduction 和 α(alpha)-conversation (性质就是 alpha-equivalence)
就“实现了一门编程语言”
啊我找到了个很赞的教程

此外,一个范畴(category) 还有以下属性(要不然就和图没有区别了)

+ 封闭律:态射可以组合
y ~> z => x ~> y => x ~> z
+ 结合律(associative):态射的组合具有结合性
(x · y) · z = x · (y · z)
只满足以上两点的图被称为半群(semigroup)
+ 同一律:有一个箭头 a -> a 指向对象自己

态射就是状态的创建者。对象本身是多级态射构造出的映射组合

class Category (c :: * -> * -> *) where
(.) :: (c y z) -> (c x y) -> (c x z)
id :: c a a

c = (->) 的时候,就是

class Category (c :: * -> * -> *) where
(.) :: (c y z) -> (c x y) -> (c x z)
id :: forall a. c a a

type Hask = (->) :: * -> * -> *
instance Category Hask where
(f . g) x = f (g x)

class 定义 Haskell 的 typeclass,它给某个类型定义上面操作的规范(然后可以有 instance
后面的 where 跟着一群成员函数的类型签名

forall a. c a a 的意思是这里的 a 可能是很多种类型,比如 Int, String, Float
所以说是『对于所有』 a 都有 id :: c a a
id :: a -> a
可以视为 id :: forall a. a -> a

箭头也可以用来指代对象,毕竟对象都是 (Monoid) 箭头从 id :: a 态射来的
(比如 Nat 的 id=0, add1 = (+1))
data Nat = O | S Natid 就是它的架构器 O :: Nat, add1 箭头就是 S :: Nat -> Nat

addOne = S :: Nat -> Nat
two = addOne O
seven = let addFive = S . S . S . S . addOne in addFive two
add1, mutiply, id 都是对象之间的态射,可是范畴之间也可以存在态射的变换

class (Category c, Category d) => Functor t c d where
fmap :: (c a b) -> d (t a) (t b)

然后就把箭头们映射到了新范畴,比如 (String -> Int) 变成 List String -> List Int?
在 C, D 都是 (->) 的情况下

class Functor t where
fmap :: (a -> b) -> t a -> t b

这样的个 typeclass,把 ("1" -> 1), (["a"] -> "a")
弄成什么的....

范畴只是抽象而已,然后 类型的变化 也是一种实例 或许

Monad 是自函子(Endofunctor) 范畴上的含宏半群(Monoid)

自函子 就是从范畴到同一个范畴的 函子

type Endofunctor t c = Functor t c c

class Endofunctor t c => Monad m c where
eta :: a -> m a
mu :: m m a -> m a

然后 flatMap 就 怎么办 呢?

我们可以先 fmap :: ... -> d (t a) (t b) 了,再去 mu 一下

(>>=) :: Monad m => m a -> (a -> m b) -> m b

m >>= f = (mu . eta :: forall a. m a -> m b) . fmap f m

代码是从那个 grokking monad 抄袭的
所以有偏差 我不负泽(
总之我很辣鸡 然后什么都 不知道 对不起....
#life #Book 小说推荐

《茶花女》 名著、爱情、悲剧、法国、老故事、一颗赛艇
很喜欢里面男主和女主的故事,非常敬佩女主茶花女
《天贼》(Hot Dream) 科幻、宇宙、未来、批判性
《魔道祖师》 网络小说、修仙
是蛮一颗赛艇的,不过自控力不好就别看了,错别字也有一些,作者拼音打的
《白夜行》 日本、侦探、小说、悲剧、崩坏
《嫌疑人 χ 的献身》 日本、侦探、小说、学者、悲剧、崩坏
《悖论 13》 日本、侦探、小说、灾难、科幻
《侦探俱乐部》 日本、侦探、小说、日常
《》
This media is not supported in your browser
VIEW IN TELEGRAM
I am angry!!!! 我可是推荐了好多好看的东西了,要我再写一遍么?不一定想得起来啊!!!