duangsuse::Echo
[DuangSUSE@duangsuse]~/Projects% ./BinOps Sigma :: + - * / ** mod unm logN sin cos tan 0xFF_FF 2.1 1+2+3 Σ We got: 1+2+3 = Just ((1.0 + 2.0) + 3.0) = 6.0 2**2 ** 3 Σ We got: 2**2 ** 3 = Just (2.0 ** (2.0 ** 3.0)) = 256.0 unm 2 + 43 ** 4 + 2 Σ We got: unm…
有一个小细节: #pl #algorithm
提到 pretty,虽然我们可以把
Add
Rat 1
Rat 2
这样的树给安全地输出成
但是如果输出成
(2 + 1) * 2
本来是
Mul
Add
Rat 2
Rat 1
Rat 2
你这么一整,就成了
Add
Rat 2
Mul
Rat 1
Rat 2
语义不对。
有两种解决方案,一是对于每个二元子节点访问,dump 后再 parse 一遍,结果相同就返回无括号版本,否则返回有括号保险版
优点是肯定有效(而且不需要专门写解析器外的算法)
缺点... 我就不用说了,别说 Haskell 里那个 Text.ParserCombinator.ReadP Monad 解析组合子了,其他的非得再解析一遍,咸得🥚疼
还有一种方案可以处理这种问题(排除二元 / 一元在一起的坑爹情况,不过其实也都是一个道理,判断出要加括号的 case 加括号,不加的不用加)
要输出
如果是正常情况,+ 的优先级没有 * 高,所以往往 * 是 + 的子节点,而不是上面这种情况
推广来说,就是发现自己左节点优先级没有自己高,就可以不带括号输出,相等则要看结合性情况(左结合右结合都要判左右手,判自己的就是左结合左手应该是自己、右结合右边应该是自己,否则就打破了结合性)
输出
最后一段属于推销可以不看(
当然有没有第三种方法呢?档燃有啊!
就是使用 RangeMap 和 ReverseMap,在解析的时候就加上空格信息(当然也包括括号信息)喽!
然后保存这些信息,到时候如果要输出可以复用
提到 pretty,虽然我们可以把
Add
Rat 1
Rat 2
这样的树给安全地输出成
(1 + 2) 的形式,但是肯定还是有人嫌太长(括号根本不需要)但是如果输出成
1 + 1 的形式呢,就会出现下面的问题(2 + 1) * 2
本来是
Mul
Add
Rat 2
Rat 1
Rat 2
你这么一整,就成了
2 + 1 * 2 了Add
Rat 2
Mul
Rat 1
Rat 2
语义不对。
有两种解决方案,一是对于每个二元子节点访问,dump 后再 parse 一遍,结果相同就返回无括号版本,否则返回有括号保险版
优点是肯定有效(而且不需要专门写解析器外的算法)
缺点... 我就不用说了,别说 Haskell 里那个 Text.ParserCombinator.ReadP Monad 解析组合子了,其他的非得再解析一遍,咸得🥚疼
还有一种方案可以处理这种问题(排除二元 / 一元在一起的坑爹情况,不过其实也都是一个道理,判断出要加括号的 case 加括号,不加的不用加)
要输出
(2 + 1) * 2 这个树,其实就是访问 Mul 节点的时候,判断一下子节点是否打破了运算符优先级如果是正常情况,+ 的优先级没有 * 高,所以往往 * 是 + 的子节点,而不是上面这种情况
推广来说,就是发现自己左节点优先级没有自己高,就可以不带括号输出,相等则要看结合性情况(左结合右结合都要判左右手,判自己的就是左结合左手应该是自己、右结合右边应该是自己,否则就打破了结合性)
输出
(Mul (Add x y) y') 这种的,就给子节点加上括号再输出"(" ++ dump x' ++ ") * " ++ dump y'
就不会有格式化错误的问题了最后一段属于推销可以不看(
当然有没有第三种方法呢?档燃有啊!
就是使用 RangeMap 和 ReverseMap,在解析的时候就加上空格信息(当然也包括括号信息)喽!
然后保存这些信息,到时候如果要输出可以复用
https://github.com/996icu/996.ICU/blob/647be115cf640f7e0879321361abfbee4ac1f4b7/archived/licenses%5BWIP%5D/tools/gen-license-rs/src/main.rs
https://github.com/996icu/996.ICU/blob/647be115cf640f7e0879321361abfbee4ac1f4b7/archived/licenses%5BWIP%5D/tools/test-gen-license/src/test_go.rs
说起来,我差点以为 996.icu 是 Rust 写的呢... Rust 和 Go 也该学学了,虽然我连 C++ 都不太会...
说起来, #Rust 还有点可怜,996.icu 的支持者用 Rsut 创建了 Go Python Rust 三语的 tests,可是 Rust 版本的测试却没有
https://github.com/996icu/996.ICU/blob/647be115cf640f7e0879321361abfbee4ac1f4b7/archived/licenses%5BWIP%5D/tools/test-gen-license/src/test_go.rs
说起来,我差点以为 996.icu 是 Rust 写的呢... Rust 和 Go 也该学学了,虽然我连 C++ 都不太会...
说起来, #Rust 还有点可怜,996.icu 的支持者用 Rsut 创建了 Go Python Rust 三语的 tests,可是 Rust 版本的测试却没有
GitHub
996icu/996.ICU
Repo for counting stars and contributing. Press F to pay respect to glorious developers. - 996icu/996.ICU
duangsuse::Echo
左结合: 总不可能这样来『兼容』嵌套的二元运算 add$2 = num "+" num add$3 = num "+" num "+" num add = add$2 | add$3 也不可能来这样 op = "+" | "-" | "*" | "/" bin = num { op num } 为啥解析的时就能创建好的结构,非得解析完了再去创建? 当然可以这样 bin = (num|bin) op num 就是左递归,可是就不方便 然后介绍了一个 chainr1 和 chai…
所以 RankNTypes 为啥要用 forall 呢? #haskell #cs #pl #plt
我们的类型系统,主要还是通过类型检查器『Type Checker』影响到我们编程的
比如
是
如果我们要这么写:
所以,Type checker 就报错了,因为它按照基本法🐸以为
这里 RankN 的 N 是 1,不变态(皮一下,不是我说的
Prelude> foo = (\f -> (f True, f 'a'))
<interactive>:2:25: error:
• Couldn't match expected type ‘Bool’ with actual type ‘[Char]’
• In the first argument of ‘f’, namely ‘"abc"’
如果我们使用 Rank N Polymorphism 呢?
Prelude> foo = (\f -> (f True, f "abc")) :: (forall a. a -> a) -> (Bool, String)
Prelude> foo id
(True,"abc")
我们发现,现在这个 a 可以『同时』是 Char 和 Bool 了
因为我们说『foo 的输入是 a -> a,而这个 a 是这个函数它局部的限制,不是 foo 里的 a 全都得是某个类型』
参考:范畴论完全装逼手册
没错,写 Haskell、Agda、Scala 就单单是为了装逼... 🤪
复制过来方便对比,从侧面就能看到其实我也不是很擅长完全理解再自己编出示例程序...
我们的类型系统,主要还是通过类型检查器『Type Checker』影响到我们编程的
{-# LANGUAGE RankNTypes #-}
foo :: (forall a. a -> a) -> (Char, Bool)
foo f = (f 'c', f True)
∀forall,就是说对于所有可能的类型选项,都有 ... 成立比如
(id :: forall a. a -> a)
在 a 类型是 Int 的时候成立,是
String 的时候也成立class Show a where再比如
showsPrec :: Int -> a -> ShowS
show :: a -> String
showList :: [a] -> ShowS
{-# MINIMAL showsPrec | show #-}
show :: forall a. Show a => a -> String
show, a 是 Int 时有 show :: Int -> String、是 Bool 时也有 show :: Bool -> String
只要前提条件 『a 类型有一个 Show 的实例 instance』成立就有 show :: a -> String
这段代码里,foo 的类型,如果不使用 RankNTypes,这么表示(虽然不能用,因为后面的程序逻辑问题)foo :: forall a. (a -> a) -> (Char, Bool)看到没有?这个
forall 全称限定是 foo :: 里面的如果我们要这么写:
foo f = (f 'c', f True)上面的类型签名是说,这个 foo 是一个接收函数
(a -> a) 返回元组 (Char, Bool) 的函数,这里 a 只有一个(要么然是 Char 要么然是 Bool 要么然是...)所以,Type checker 就报错了,因为它按照基本法🐸以为
f :: a -> a 在第一次 beta-reduction (f True) 的时候类型已经确定是 Bool 了,不知也可以是 Char这里 RankN 的 N 是 1,不变态(皮一下,不是我说的
Prelude> foo = (\f -> (f True, f 'a'))
<interactive>:2:25: error:
• Couldn't match expected type ‘Bool’ with actual type ‘[Char]’
• In the first argument of ‘f’, namely ‘"abc"’
如果我们使用 Rank N Polymorphism 呢?
foo :: (forall a. a -> a) -> (Char, Bool)
这里 RankN 的 N 是 2Prelude> foo = (\f -> (f True, f "abc")) :: (forall a. a -> a) -> (Bool, String)
Prelude> foo id
(True,"abc")
我们发现,现在这个 a 可以『同时』是 Char 和 Bool 了
因为我们说『foo 的输入是 a -> a,而这个 a 是这个函数它局部的限制,不是 foo 里的 a 全都得是某个类型』
参考:范畴论完全装逼手册
没错,写 Haskell、Agda、Scala 就单单是为了装逼... 🤪
复制过来方便对比,从侧面就能看到其实我也不是很擅长完全理解再自己编出示例程序...
rank2 :: forall b c . b -> c -> (forall a. a -> a) -> (b, c)用 Scala 写,所以 JVM 还是很 FP 的?(....
rank2 b c f = (f b, f c)
rank2 True 'a' id
-- (True, 'a')
def rank2[B, C](b: B, c: C)(fnk: Id ~> Id): (B, C) =
(fnk(b), fnk(c))
rank2(true, 'a')(FunctionK.id[Id])
duangsuse::Echo
所以 RankNTypes 为啥要用 forall 呢? #haskell #cs #pl #plt 我们的类型系统,主要还是通过类型检查器『Type Checker』影响到我们编程的 {-# LANGUAGE RankNTypes #-} foo :: (forall a. a -> a) -> (Char, Bool) foo f = (f 'c', f True) ∀forall,就是说对于所有可能的类型选项,都有 ... 成立 比如 (id :: forall a. a -> a) 在 a…
Forwarded from Rachel 碎碎念 (IFTTT)
真的 不是很明白为什么国内的游戏都有几十上百个区 而且区与区之间数据不互通…
感觉这种设计极其落后而且反人类
9102 年了还不普及 CDN 和多数据中心设计…— Rachel Miracle. (@tangrui003) April 28, 2019
感觉这种设计极其落后而且反人类
9102 年了还不普及 CDN 和多数据中心设计…— Rachel Miracle. (@tangrui003) April 28, 2019
Twitter
Rachel Miracle.
真的 不是很明白为什么国内的游戏都有几十上百个区 而且区与区之间数据不互通… 感觉这种设计极其落后而且反人类 9102 年了还不普及 CDN 和多数据中心设计…
This media is not supported in your browser
VIEW IN TELEGRAM
duangsuse::Echo
抄了几个小时,Monad 真的是很难尝试与作者拥有相同的想法...
你们体验一下,就会发现 Haskell 的 Monad Parserc 框架写起来其实是很魔性的,
组合子基本上也就是顺序解析和 branch 这两个需求,
这个 parser 通过 [(a, String)] 来存储当前解析结果(val & rest),和 ReadP 是一样的
如果不是因为 Haskell 要求完全纯的计算(就是函数单靠组合不产生任何副作用,不允许任何外部输入也不能对函数外环境造成影响)
其实可以更好些,虽然 Haskell 写的也非常方便
组合子基本上也就是顺序解析和 branch 这两个需求,
这个 parser 通过 [(a, String)] 来存储当前解析结果(val & rest),和 ReadP 是一样的
如果不是因为 Haskell 要求完全纯的计算(就是函数单靠组合不产生任何副作用,不允许任何外部输入也不能对函数外环境造成影响)
其实可以更好些,虽然 Haskell 写的也非常方便
NaiveParserc.hs
3.5 KB
duangsuse::Echo
#matlab https://github.com/BaseMax/MatlabMatrixProject/blob/master/BiggestValueMatrix.m 啊?为啥这么简单的算法要发上来... 我还以为是要 show SIMD 优化的呢... 🤔???
弄了半天我才猜到
function [lv1, lv2] = Name(ArgType)是这样的啊
end
duangsuse::Echo
#matlab https://github.com/BaseMax/MatlabMatrixProject/blob/master/BiggestValueMatrix.m 啊?为啥这么简单的算法要发上来... 我还以为是要 show SIMD 优化的呢... 🤔???
可是,即使是线性查找也有点奇怪呢?... 不清楚呢
https://github.com/BaseMax/MatlabMatrixProject/blob/master/BiggestValueMatrix.m#L8
https://github.com/BaseMax/MatlabMatrixProject/blob/master/BiggestValueMatrix.m#L10
https://github.com/BaseMax/MatlabMatrixProject/blob/master/BiggestValueMatrix.m#L12
https://github.com/BaseMax/MatlabMatrixProject/blob/master/BiggestValueMatrix.m#L17
Matlab 已经很不怎么优化了(所谓的『数据处理语言』,我个人觉得还不如直接 Julia),还这样一遍一遍找 O(n) 两遍... 尽可能一次弄完吧
类似 #Haskell #fp 的 banana split:
https://github.com/BaseMax/MatlabMatrixProject/blob/master/BiggestValueMatrix.m#L8
maximum=Matrix(1,1);反正要被替换,为什么不直接随便初始化个简单的...
https://github.com/BaseMax/MatlabMatrixProject/blob/master/BiggestValueMatrix.m#L10
for i=1:rows没有考虑到 Matrix 为 0x~ 维度的情况
https://github.com/BaseMax/MatlabMatrixProject/blob/master/BiggestValueMatrix.m#L12
if maximum <= Matrix(i,j);
其实等于的时候不必替换https://github.com/BaseMax/MatlabMatrixProject/blob/master/BiggestValueMatrix.m#L17
[row_max column_max] = find(A == maximum);
别这样,扫描一遍已经够了,为啥要再来第二遍...Matlab 已经很不怎么优化了(所谓的『数据处理语言』,我个人觉得还不如直接 Julia),还这样一遍一遍找 O(n) 两遍... 尽可能一次弄完吧
类似 #Haskell #fp 的 banana split:
length = foldl (\x y -> succ y) 1productLength 比 productLength' 要好,它只 travelse 了一遍,没有不必要地再去算第二遭
product = foldl (*) 1
productLength = foldl ( \(a0, a1) x -> (x * a0, succ a1) ) (1, 1)
productLength' xs = (product xs, length xs)
GitHub
BaseMax/MatlabMatrixProject
Scan and find the biggest number's value of the a matrix. - BaseMax/MatlabMatrixProject