Forwarded from dnaugsuz
thx 不过 照 LIF 的看法,只发酷安泡泡链接是不行的,没专门的客户端不能看
duangsuse::Echo
你们就不要说我没能力弄这些东西了,我当然不是幼稚到只会发广播的水平
本来想先讲一下上次那个汉诺塔(Hanoni)的问题的:
其实就是有一个要点,上面 Haskell 例程的 A B C 塔不一定非得是 A B C
上面维基里的描述,其实涉及到了递归
而我之前分析归纳出的
Haskell 代码对应的自然语言就是这么说:
如果你已经搞清楚了子程序的定义,诸如
这里最重要的就是
在编写此子程序时,你只需要考虑到上面这个定义,然后是基线条件『
之前可行的那个交换方法推广一下,使用这个抽象一弄就完成了(它只是加了一个 n 作为剩余步数计数,基线条件)
现在干脆临时从使用者的角度和大致的算法环境检查上分析一下 liba.so 算了
其实就是有一个要点,上面 Haskell 例程的 A B C 塔不一定非得是 A B C
上面维基里的描述,其实涉及到了递归
假设有 A、B、C 三个塔,A 塔有 N 块盘,目标是把这些盘全部移到 C 塔。那么先把 A 塔顶部的 N − 1 块盘移动到 B 塔,再把 A 塔剩下的大盘移到 C,最后把 B 塔的 N − 1 块盘移到 CA B C 不一定非得是我们『最开始』的 A B C,它还可以是『临时』子程序里的 A B C
而我之前分析归纳出的
naive-swap 其实就是一个『length(A) = 2 时的这种变换子程序思路』def naive-swap(src, buf, dst) = src(smaller) » buf; src(greater) » dst; buf(smaller) » dst假设
A=[1,2],naive-swap(A,B,C) 即为 A»B;A»C;B»C
问题解决过程中,所谓的 A 塔可以被归纳抽象为『源塔』,B 塔可以被认为是『变序塔』,C 塔则可以认为是『目标塔』Haskell 代码对应的自然语言就是这么说:
子程序 Hanoni (剩余步数,元组:源塔、倒序塔、目标塔)比如我之前的例子
如果 『只需要一步即可完成(源塔)到(目标塔)的移动』
则打印 “$(源塔) -> $(目标塔)”
否则,
Hanoni(剩余步数 - 1,(源塔、目标塔、倒序塔))
Hanoni(1,(源塔、倒序塔、目标塔))
Hanoni(剩余步数 - 1,(倒序塔、源塔、目标塔))
A=[1,2,3]
因为我讲得很清楚了,所以就只看递归调用中塔们的变化Hanoni n (src, buf, dst)递归最好理解的方式就是弄清楚子程序的定义:它到底做什么?
Hanoni 3 (A, B, C)
= Hanoni 2 (A, C, B)
(1)
> Hanoni 1 (A, B, C)
* A -> C
> Hanoni 2 (B, A, C)
(2)
(1) = Hanoni 2 (src=A, buf=C, dst=B)
= Hanoni 1 (src=A, buf=C, dst=B)
* A -> B
> Hanoni 1 (A, B, C)
* A -> C
> Hanoni 1 (B, A, C)
* B -> C
(2) = Hanoni 2 (src=B, buf=A, dst=C)
= Hanoni 1 (src=B, buf=C, dst=A)
* B -> A
> Hanoni 1 (A, B, C)
* B -> C
> Hanoni 1 (A, B, C)
* A -> C
如果你已经搞清楚了子程序的定义,诸如
reverse,每一步都把 reverse xs ++ [x]
那就不难分析了,需要递归的时候直接利用它的定义『reverse 一个 length >1 列表的顺序』即可这里最重要的就是
Hanoni 本身的定义:它接受『源塔、倒序塔、目标塔』的名字,还有『我还要移动多少次』也即『要移动多少个盘子』(剩余步数)这个额外信息Hanoni n (A, B, C) 执行的操作说到底是『从 A 上移动 n 个盘子到 C 上,利用 B 交换一下顺序』在编写此子程序时,你只需要考虑到上面这个定义,然后是基线条件『
n = 1 时只需要一步即可完成移动』,不难解决此问题,不过这里的确是有个额外的逆序限制,可以按照我昨天写了一晚上的做法推导出来递归时每一步的操作之前可行的那个交换方法推广一下,使用这个抽象一弄就完成了(它只是加了一个 n 作为剩余步数计数,基线条件)
现在干脆临时从使用者的角度和大致的算法环境检查上分析一下 liba.so 算了
This media is not supported in your browser
VIEW IN TELEGRAM
Forwarded from duangsuse Throws
Forwarded from duangsuse Throws
说个好笑的,Dnf(Dandified Yum,Fedora 28 的软件包管理器)离线更新的时候那个下载日志还是什么居然积累到了 18G,把我的 SSD 塞炸了... hhhhh #Haha
duangsuse::Echo
你们就不要说我没能力弄这些东西了,我当然不是幼稚到只会发广播的水平
This media is not supported in your browser
VIEW IN TELEGRAM
Forwarded from duangsuse Throws
Forwarded from duangsuse Throws
#School 这周马上就要放寒假了(还有一个月) 🤔
duangsuse 的安排嘛... 其他的都好了,本来每周就是讲东西为主,然后本周买了别的东西,画了几张画,最后书什么的基本没看。嗯嗯。
这周就是讲点东西,发点照片,没了。
顺便说一下,推荐有打印机又看过书的大家可以没事带几张 papper (比如之前那个代数程序逻辑的 fold.pdf,我在 USTC 中科大学生的分享里淘到的,当然论文基本都是公开的你们可以随便找个大学比如 Illinois 的 CS 系看...)到例如公交车的地方看看,因为我觉得吧,公交车之类的地方可能思维都比较开放一些,学习起来比较有效果,可惜就是很慢就是了
至于我上面提到的 papper A tutorial on the universality and expressiveness of fold 可以在 这里(Nottingham in UK 大学)下载 #papper #FP #CS
个人觉得... 虽然有些不常见的词,但是有一定函数式编程和程序分析变换、形式化证明基础的人虽然可能看很久但收获不错。
见好就收。
duangsuse 的安排嘛... 其他的都好了,本来每周就是讲东西为主,然后本周买了别的东西,画了几张画,最后书什么的基本没看。嗯嗯。
这周就是讲点东西,发点照片,没了。
顺便说一下,推荐有打印机又看过书的大家可以没事带几张 papper (比如之前那个代数程序逻辑的 fold.pdf,我在 USTC 中科大学生的分享里淘到的,当然论文基本都是公开的你们可以随便找个大学比如 Illinois 的 CS 系看...)到例如公交车的地方看看,因为我觉得吧,公交车之类的地方可能思维都比较开放一些,学习起来比较有效果,可惜就是很慢就是了
至于我上面提到的 papper A tutorial on the universality and expressiveness of fold 可以在 这里(Nottingham in UK 大学)下载 #papper #FP #CS
个人觉得... 虽然有些不常见的词,但是有一定函数式编程和程序分析变换、形式化证明基础的人虽然可能看很久但收获不错。
见好就收。
#Machl #AI 非常希望去学习一些自然语言处理和机器学习相关的技术
至于面向 Compiler 技术向的解析技术,我也不甚了解,我没写过 ANTLR,不知道 LALR、LL、LR 解析算法是怎么执行的,不知道自底向上分析和自底向下推导的区别,不了解 PCRE Regex 匹配算法,不清楚 infix operator 们的优先级和结合性的问题,
#parser #NLP 至于自然语言处理(NLP),我发现因为可能是考虑过一个比较有幼稚 niave 的梦想『Semic 机器人』的原因,我对结构化自然语言还有点直觉
但是我不是特别了解自然语言,也不了解音标记法(当然不是一个层面的东西)
我觉得这个可以考虑多去分析一些小说什么的来提升
至于机器学习,我看过冰封他学姐写的博文,虽然因为我完全没有 ANN(人工神经网络)和机器学习的基础(其实我有一点 KNN 回归量化评估分析的基础,《算法图解》看的)(数学上,我们最近高二也在上回归,不过和 KNN 那种简单的回归而不是函数回归没有特别大的关系)
理解非常的困难,我不知道啥是 Layer、不知道啥是导数、不知道啥是反向传播啥是 bootstrap 函数,但幸亏我有函数式的基础,所以
(事实是,很多(尤其是对于一些比较 trivial 的业务范围,比如 #Android 开发和 #Web 前端来说)工业界的程序员压根不能理解 FP 范式的一些东西,或者使用的理解式变通太多了,以至于直觉不太好)
比如说这个 Haskell 里一些 function 扩展和 Monad 们的 Kotlin 版本,大家可以看看自己看不看得懂(挫败感?
想必很多不是特别熟悉 Kotlin,而只是把 Kotlin 写成 Java (甚至 Java 7 而不是 8)的程序员要开始烧脑一战了(
至于面向 Compiler 技术向的解析技术,我也不甚了解,我没写过 ANTLR,不知道 LALR、LL、LR 解析算法是怎么执行的,不知道自底向上分析和自底向下推导的区别,不了解 PCRE Regex 匹配算法,不清楚 infix operator 们的优先级和结合性的问题,
infixl infilr 傻傻分不清(几乎)#parser #NLP 至于自然语言处理(NLP),我发现因为可能是考虑过一个比较有幼稚 niave 的梦想『Semic 机器人』的原因,我对结构化自然语言还有点直觉
但是我不是特别了解自然语言,也不了解音标记法(当然不是一个层面的东西)
我觉得这个可以考虑多去分析一些小说什么的来提升
至于机器学习,我看过冰封他学姐写的博文,虽然因为我完全没有 ANN(人工神经网络)和机器学习的基础(其实我有一点 KNN 回归量化评估分析的基础,《算法图解》看的)(数学上,我们最近高二也在上回归,不过和 KNN 那种简单的回归而不是函数回归没有特别大的关系)
理解非常的困难,我不知道啥是 Layer、不知道啥是导数、不知道啥是反向传播啥是 bootstrap 函数,但幸亏我有函数式的基础,所以
fun Scale(d: Weight) = { lf: LossFunction -> { w: Weight -> d * lf(w) } } 这种 FP 风格的 #Kotlin 代码我至少还不至于看不懂,给我尝试去理解这类玩意创造了一个最基本的条件 — 如果你连别人说啥都搞不懂,怎么 get 得到知识点呢?(事实是,很多(尤其是对于一些比较 trivial 的业务范围,比如 #Android 开发和 #Web 前端来说)工业界的程序员压根不能理解 FP 范式的一些东西,或者使用的理解式变通太多了,以至于直觉不太好)
比如说这个 Haskell 里一些 function 扩展和 Monad 们的 Kotlin 版本,大家可以看看自己看不看得懂(挫败感?
fun <T : Any> T?.toMaybe() = this?.let(::Some) ?: None
尤其是最后那个 #FP CoinductiveList,我也是最近才理解,而这个 fibonacci Sequence 才是最骚的(也很能体现一个 CS lover 的水平 — 你究竟只能算是『工程师』还是能算是『爱好者』呢?):fib = 1 : 2 : zipWith (+) fib (tail fib)(这里是有限构造的 List,不是 Coinductive 的,虽然 Haskell 是 Built-in Laziness 所以可以当成是 Coinductive 的,对应到 Kotlin 就是 Kotlin std 的 Sequence)
Prelude> take 10 fib
[1,2,3,5,8,13,21,34,55,89]
-- 数学定义
fib' 1 = 1
fib' 2 = 2
fib' n = fib (n - 1) + fib (n - 2)
想必很多不是特别熟悉 Kotlin,而只是把 Kotlin 写成 Java (甚至 Java 7 而不是 8)的程序员要开始烧脑一战了(
GitHub
ice1000/Ruiko.kt
Kotlin version of Ruiko.fs. Contribute to ice1000/Ruiko.kt development by creating an account on GitHub.
#CSharp 好像早就有了啊,Java 的 TryWithResource(
下面那个我觉得好像
至于
有点类似于 Haskell 里的 Map(?其实是
好像没有
这里
递归数据类型。看不懂的复习一下二叉树。OI 基础内容
举个例子,一个字符串二叉树,假设我们是在做一个计算器(因为这个例子很常见)
Closeable)不就是和 CSharp 学的吗?下面那个我觉得好像
class T 可以改成这样(个人看法,程序逻辑不等价class CouterEnumeratorExample {
private int _counter = 0;
public CounterEnumeratorExample() {}
public int Current => _counter;
public bool moveNext() {
return ++_counter < 5;
}
public CouterEnumeratorExample GetEnumerator() => this;
}
(++_counter < 5) 的修改会让 enumerable 的 Current 值(也即 forEach 的 application 参数范围)范围在 0..4 (也即 (0, 5]) 区间内,_counter 的范围在 0..5 的区间内至于
moveNext() 返回 false 之后 _current 我觉得就是没有必要检查其值的,反正 Enumerator 就是用来枚举 Travelse 的有点类似于 Haskell 里的 Map(?其实是
Data.Travelsable 不过我因为比较入门所以太关心广义的 map 操作了好像没有
instance Functor(其实是我误会了... (其实是我不够了解 Haskell...),但是有 mapM(onad) 可以用-- class (Functor t, Foldable t) => Traversable t上面的代码 [origin] 实现了对二叉树(Binary Trees)的前序遍历(先访问左子节点、再是本节点、再是右子节点)(当然 Tree 还不是 Functor,没有实现 fmap 所以上面的代码不是拿来运行的,我也懒得补写)(其实是不会写,跑)
data Tree a = Empty | Leaf a | Node (Tree a) a (Tree a)
instance Traversable Tree where
traverse f Empty = pure Empty
traverse f (Leaf x) = Leaf <$> f x
traverse f (Node l k r) = Node <$> traverse f l <*> f k <*> traverse f r
import Control.Applicative它是说这必须是顺序调用,不能瞎 Lazy(Sequential application)
(<*>) :: f (a -> b) -> f a -> f b
这里
f 是一个 Functor
#Haskell #Learn 给一些还完全不会 Haskell 的人科普一下(虽然我也不会data Tree a是一个类型(
Tree a),a 可以理解为类型参数(泛型)Empty是一个 无参架构器 Empty
Lea
f a 是一个包含 a 类型数据的架构器 LeafNode (Tree a) a (Tree a) 是包含左右两个 Tree a 类型『子树』和本节点数据的架构器 Node递归数据类型。看不懂的复习一下二叉树。OI 基础内容
举个例子,一个字符串二叉树,假设我们是在做一个计算器(因为这个例子很常见)
type String = List Char
type StringTree = Tree String
tree0 = Empty
tree1 = Node (Leaf "1") "+" (Leaf "1")
tree2 = Node (Node (Leaf "2") ">" Leaf "1") "<" (Node Leaf "1" "+" Leaf "1")
tree3 = Node Empty "||" Leaf "10"
我们可以(eval 求值函数就不写了,虽然写出来也不是多长)(看这里)class (Functor t, Foldable t) => Traversable t(好吧,我不熟悉 Haskell,我下次学...)
traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
printBinaryTree bt = traverse print
duangsuse::Echo
#CSharp 好像早就有了啊,Java 的 TryWithResource(Closeable)不就是和 CSharp 学的吗? 下面那个我觉得好像 class T 可以改成这样(个人看法,程序逻辑不等价 class CouterEnumeratorExample { private int _counter = 0; public CounterEnumeratorExample() {} public int Current => _counter; public bool moveNext()…
#recommended 所以说,Haskell 应该怎么写???
Haskell 不是拿来写 HelloWorld 这种简单到不要不要的程序的,也不是拿来用 Guard Pattern、List Comprehension
Haskell、Scala、Scheme、CoffeeScript 之类的 FP 语言不是让人拿来写一点
对于优秀的程序员来说 FP 既不应该是『可望可谈而不可及』的白象也不应该是非常表面的一些东西(比如单纯字面上的『本本主义者』什么纯函数啊、什么递归替代循环啊、什么惰性求值模式匹配啊),FP 爱好者们应该从程序们里面看到一种... 一种... 思考的快乐?这是很多『称职』的工程师们做不到的 — 对他们来说这是『头疼』
FP 不应该是什么头衔,不要拿它去做什么非常功利的事情,我想没有人想东施效颦或者当什么演员
真正的 FP 爱好者,他们从来都不会去谈自己喜欢 FP、FP 基本特色这类非常 trivial 的事情,技术水平都是非常自然的从自己的代码和讨论里流露出来的
一上 Haskell 至少是
当然不能说 FP 或者 OOP 都是拿来表示一切的,都有各自擅长的领域,比如 FP 要拿来写 Android 应用可能就有点高射炮打蚊子的意思了(可能根本用不到啥好玩的特性,写不出多好看的程序来,一大堆
有的时候就是这样的,OOP 是表述式,FP 是定义式的风格,二者各自适合不同的程序,定义式有些情况下表述程序起来比较不方便
(偶尔想说一些这样的东西,但其实我不是特别了解所以把握不好,get 到我的意思就好了(请,emmmmm.....
Haskell 不是拿来写 HelloWorld 这种简单到不要不要的程序的,也不是拿来用 Guard Pattern、List Comprehension
[x * 2 | x <- l, isOdd x] 这种简直语法糖的东西的,这种事情应该留给 JavaScript 这种工业界常用的语言去做Haskell、Scala、Scheme、CoffeeScript 之类的 FP 语言不是让人拿来写一点
(for-each ...) 的,实际上单单就 FP 编程,不包含一些更高更开阔的视角,至少 Y 组合子得会定义,并且简单的递归程序,比如 filter、dropWhile 得会写对于优秀的程序员来说 FP 既不应该是『可望可谈而不可及』的白象也不应该是非常表面的一些东西(比如单纯字面上的『本本主义者』什么纯函数啊、什么递归替代循环啊、什么惰性求值模式匹配啊),FP 爱好者们应该从程序们里面看到一种... 一种... 思考的快乐?这是很多『称职』的工程师们做不到的 — 对他们来说这是『头疼』
FP 不应该是什么头衔,不要拿它去做什么非常功利的事情,我想没有人想东施效颦或者当什么演员
真正的 FP 爱好者,他们从来都不会去谈自己喜欢 FP、FP 基本特色这类非常 trivial 的事情,技术水平都是非常自然的从自己的代码和讨论里流露出来的
一上 Haskell 至少是
fib = 1 : 2 : zipWith (tail fib) 这种级别,要不然还是 Java 之类简单的语言靠谱,或者混合 Kotlin 也行当然不能说 FP 或者 OOP 都是拿来表示一切的,都有各自擅长的领域,比如 FP 要拿来写 Android 应用可能就有点高射炮打蚊子的意思了(可能根本用不到啥好玩的特性,写不出多好看的程序来,一大堆
do notation,函数式平时的感觉和定义式风格都没有了)有的时候就是这样的,OOP 是表述式,FP 是定义式的风格,二者各自适合不同的程序,定义式有些情况下表述程序起来比较不方便
(偶尔想说一些这样的东西,但其实我不是特别了解所以把握不好,get 到我的意思就好了(请,emmmmm.....
#SQL 我跟你们讲啊,我之前连 SQL
Python:
这不是个好例子,不过我很随意的.... 😕
JOIN 都不知道是在求并集的意思(...Python:
land = set(['rabbit', 'bear', 'duck', 'polebear'])
sky = set(['duck', 'swan'])
print(land & sky)
btw. 陆生 = Terrestrial这不是个好例子,不过我很随意的.... 😕
Forwarded from 羽毛的小白板