duangsuse::Echo
虽然最后我还是放弃了继续写这些... 即便除了 bot 逻辑外的都写完了
This media is not supported in your browser
VIEW IN TELEGRAM
虽然 Scala 再去继承一下 TelegramBots 的 Api Class,使用 postfix operators 和 implicit conversation 和比 Kotlin 搞基的 Pattern matching 应该可以实现更优秀的可读性,而且这应用逻辑本身就不是多复杂...
duangsuse::Echo
虽然 Scala 再去继承一下 TelegramBots 的 Api Class,使用 postfix operators 和 implicit conversation 和比 Kotlin 搞基的 Pattern matching 应该可以实现更优秀的可读性,而且这应用逻辑本身就不是多复杂...
比如说,Scala 的 Postfix Operators
res0: String = Hello, duangsuse
scala> "duangsuse".!
res1: String = Hello, duangsuse
scala> "duangsuse"!
res2: String = Hello, duangsuse
比起 Jawa, Kotlin 里不断
import scala.language.implicitConversionsscala> !"duangsuse"
import scala.language.postfixOps
final implicit class HelloableString(val m: String) {
def ! : String = s"Hello, $m"
def unary_! = this.!
override def toString = m
}
res0: String = Hello, duangsuse
scala> "duangsuse".!
res1: String = Hello, duangsuse
scala> "duangsuse"!
res2: String = Hello, duangsuse
比起 Jawa, Kotlin 里不断
execute(Query) 好多了...有的时候觉得经验和记忆力重要,因为不会记住那些接口就不能编程了呢....
即便会怎么怎么样,可能比擅长编写应用的人们更适合去学习算法什么的,但是好像也不怎么样
又有时候会觉得对模型的直觉很重要
也有时候会觉得设计和分析的能力很重要....
因为能写很多真正能让人看不懂的东西,而不是容许一切复杂性都被藏在一些简单的东西后面
所以,到底是使用接口的知识『广度』大好呢,还是分析能力『深度』大好呢... 🤔
这是一个值得考虑的问题
即便会怎么怎么样,可能比擅长编写应用的人们更适合去学习算法什么的,但是好像也不怎么样
又有时候会觉得对模型的直觉很重要
也有时候会觉得设计和分析的能力很重要....
因为能写很多真正能让人看不懂的东西,而不是容许一切复杂性都被藏在一些简单的东西后面
所以,到底是使用接口的知识『广度』大好呢,还是分析能力『深度』大好呢... 🤔
这是一个值得考虑的问题
METO 的涂鸦板
🌚 你写 PHP 7.4 的样子好像 Node.js * 新特性汇总 * RFC:箭头函数语法 * RFC:数组解构语法
上面的作为比较可以看看用 #Haskell 怎么写:
parts = ["apple", "pear"]因为 Haskell 没有『Spread operator』所以就用 (++) 替换了,虽然说 spread operator 也不是魔法的就能实现把『item』里的东西全都 flat 添加到集合里的能力了,势必也得做额外的支持
fruits = ["banana", "orange"] ++ parts ++ ["watermelon"]
fruits == ["banana","orange","apple","pear","watermelon"]
result = f [1, 2] where f = (sum . ((*2) <$>))
(putStrLn . show :: Int -> IO ()) result
其中 sum 的定义是sum [] = 0或者,用
sum (x:xs) = x + sum xs
foldl 定义(非 point-free 版本)sum xs = foldl (\ac x -> ac + x) 0 xs
(.) 就是 compose 啦((sum . ((*2) <$>))
就是(\xs -> sum (map (* 2) xs))
(*2) 是柯里化的 (*) ((*) :: Num a => a -> a -> a
拿到一个 Num a 以后还要一个 Num a(因为有交换律 transitive 所以不用考虑顺序)就可以得到乘积Forwarded from dnaugsuz
想写一个支持 Lexical Scoping JVM 上的解释器...
最近是不知道该做什么,想做的太多了,时间太少了,又不会休息... 效率低下精力损失
思量着写点异步的应用学习一下 Events/Callback/Promise/Coroutine/AwaitAsync/Threads 什么的?
Forwarded from duangsuse Throws
#info #Telegram 这周 duangsuse 将开始使用一种新的制度,可能可以提升我的工作效率和身体素质(目前应该视为首要任务) —
现在,很多东西对于 duangsuse 来说终于不是难题了,duangsuse 已经有了可以在应用层(包括异步、函数式、用户界面、计算机网络、数据库、IO 等)驰骋的能力,而且还是多语言!
所以我依然要继续学习 #CS 计算机科学了(而不是成天等着完成 XX 事情),
不过,我决定,因为每周的时间非常有限, 一周只完成大概的两件任务(任务是随便定的)
然后剩下的时间就主要是咸鱼看番( 🐟
(算是对完成速度快的鼓励
(好吧,是因为我目前好像不应该在电脑面前坐太久呢。
现在,很多东西对于 duangsuse 来说终于不是难题了,duangsuse 已经有了可以在应用层(包括异步、函数式、用户界面、计算机网络、数据库、IO 等)驰骋的能力,而且还是多语言!
所以我依然要继续学习 #CS 计算机科学了(而不是成天等着完成 XX 事情),
不过,我决定,因为每周的时间非常有限, 一周只完成大概的两件任务(任务是随便定的)
然后剩下的时间就主要是咸鱼看番( 🐟
(算是对完成速度快的鼓励
(好吧,是因为我目前好像不应该在电脑面前坐太久呢。
#algorithm #cs #net #security 🌚
这... 他们也真是太有创意了,这都能想出来(其实也不意外,像这种增加服务资源消耗的破坏性攻击也是直觉所在了...)
🤔 HashMap 的最差时间复杂度,假设是扎堆的情况下可能是 O(n**2) ?
看来还是我不了解这些算法....
我一直以为最差大不了就是 O(n) 的,线性 Map 也就是这个复杂度:
#Haskell 里,(List)Map 可以这么定义:
然后我们定义基础的 get 和 put 操作:
😫
但是,即使是 ArrayMap 的最差情况时间复杂度也只是 O(n) 啊!为啥 HashMap 就多了一个 n*...
我知道,现在流行的(比如,Lua 和 Ruby 和 PHP 的实现)散列表实现都是基于『散列桶』分配的,需要时多分配一些桶(链表),重新算散列分配操作
但那的复杂度好像也不是 O(n**2) 啊... 毕竟最差情况也就是算一次 O(1) 的散列 Key 拿储蓄对象的 bin,结果 bin 里碰撞了(不止一个 kv 被分配在某桶),那复杂度就会是 O(n) (要线性查找一遍)
这... 他们也真是太有创意了,这都能想出来(其实也不意外,像这种增加服务资源消耗的破坏性攻击也是直觉所在了...)
🤔 HashMap 的最差时间复杂度,假设是扎堆的情况下可能是 O(n**2) ?
看来还是我不了解这些算法....
我一直以为最差大不了就是 O(n) 的,线性 Map 也就是这个复杂度:
#Haskell 里,(List)Map 可以这么定义:
data ListMap k a = ListMap [(k, a)] deriving Show不能直接 derive。
Eq
然后我们定义基础的 get 和 put 操作:
import Data.Maybe (listToMaybe)
getKey :: (Eq k) => ListMap k a -> k -> Maybe a
getKey (ListMap xs) k = (snd <$>) . listToMaybe . find $ xs
where
find = filter ((== k) . fst)
putKey :: ListMap k a -> k -> a -> ListMap k a
putKey (ListMap kvs) k v = ListMap ((k, v) : kvs)
因为 Haskell 多了一层递归调用栈的空间复杂度(比如 filter 操作)... 算了,有 TCO... 算了... 和时间复杂度无关...😫
但是,即使是 ArrayMap 的最差情况时间复杂度也只是 O(n) 啊!为啥 HashMap 就多了一个 n*...
我知道,现在流行的(比如,Lua 和 Ruby 和 PHP 的实现)散列表实现都是基于『散列桶』分配的,需要时多分配一些桶(链表),重新算散列分配操作
但那的复杂度好像也不是 O(n**2) 啊... 毕竟最差情况也就是算一次 O(1) 的散列 Key 拿储蓄对象的 bin,结果 bin 里碰撞了(不止一个 kv 被分配在某桶),那复杂度就会是 O(n) (要线性查找一遍)
Forwarded from 科技圈的日常 (Jimmy Tian)
什么是哈希洪水攻击(Hash-Flooding Attack)?
「『哈希表的最差时间复杂度是 n^2』——这是一项所有软件开发人员烂熟于心的基础知识,所有人都知道,但是所有人都只是看过一眼就忘在脑后了。直到 2003 年,才第一次有人提出可以用这个东西发动网络攻击,而且效果十分之出色。」
https://www.zhihu.com/question/286529973/answer/676290355
「『哈希表的最差时间复杂度是 n^2』——这是一项所有软件开发人员烂熟于心的基础知识,所有人都知道,但是所有人都只是看过一眼就忘在脑后了。直到 2003 年,才第一次有人提出可以用这个东西发动网络攻击,而且效果十分之出色。」
https://www.zhihu.com/question/286529973/answer/676290355
duangsuse::Echo
#algorithm #cs #net #security 🌚 这... 他们也真是太有创意了,这都能想出来(其实也不意外,像这种增加服务资源消耗的破坏性攻击也是直觉所在了...) 🤔 HashMap 的最差时间复杂度,假设是扎堆的情况下可能是 O(n**2) ? 看来还是我不了解这些算法.... 我一直以为最差大不了就是 O(n) 的,线性 Map 也就是这个复杂度: #Haskell 里,(List)Map 可以这么定义: data ListMap k a = ListMap [(k, a)]…
data Maybe a = Just a | Nothing deriving Eq, Show
instance Functor Maybe where
fmap f (Just x) = Just <$> f x
fmap f Nothing = Nothing
instance Monad Maybe where
return x = Maybe x
(Just x) >>= f = f x
Nothing >>= _ = Nothing
其中 Fuctor 就是 Functor...class Category (c :: * -> * -> *) whereCategory 就是一个范畴:
id :: c a a
(.) :: c y z -> c x y -> c x z
一个图有两样东西:对象、箭头
一个半群(Semigroup)满足两个定律:
封闭律:对于所有箭头 f g,都有箭头 h = f . g
结合律:(f .g) x = f . (g . x)
当然这个 (.) 不需要理解,是什么看上面的
class Semigroup a where一个含宏半群包含一个宏元 id:
(<>) :: a -> a -> a
(<>) = mappend
class Semigroup a => Monoid a whereMonoid 也是一个范畴
mempty :: a
Functor 是对象为范畴的范畴上的箭头:
class (Category c, Category d) => Functor c d t where
fmap :: c a b -> d (t a) (t b)
这里 c 就是 Category 这个 typeclass 的 c :: * -> * -> *
它是一个 Higher Kind, 接受一个类型、再接受一个类型,返回一个类型,或者说c :: * -> * -> *
(c T) :: * -> *
Functor 就是不同范畴的映射关系,把 O 映射到 T(O)、~> 映射到 T(~>)然后对象就是箭头弄出来的变化态射,所以直接 fmap 箭头就可以了?
one = 1 — 对象 "单元" "宏元"
addOne = (+1) — 箭头 (\x -> x+1)
addOne one — 2
addOne . addOne $ one — 3
然后就有 Endofunctor "自函子",从一个范畴到同一个范畴的 Functor,它是一个范畴,对象是 Category、箭头是 Cateogry 之间的态射
type Endofunctor c t = Functor c c t
然后就有 Monad 了...class Endofunctor c t => Monad t where
eta :: c a (t a)
mu :: c (t (t a)) (t a
)
这里 t 是 (t :: * -> *), 它把一个对象 Map 到一个对象,这里是一个新 Monad定义有点区别,Haskell 的 Control.Monad 是
class Applicative m => Monad m而不是 Endofunctor, 不过 Applicative 其实是
class Functor f => Applicative f反正 Monad、Applicative 都是 Haskell 完成 "sequence computations and combine their results" 的东西...
毕竟 Haskell 是基于『那种』函数式的(而不是类似 Scheme 的逻辑即『组合函数』函数式,使用递归、允许副作用)(Haskell 就换成了基于范畴论的函数式... 这是不能引入副作用的,而 Scheme 的抽象级别没有那么高,还能看出点机器化的东西)
不过说起来我也没写过『顺序应用函数』的 R6RS Scheme 程序... 因为我不是特别擅长 Scheme
不过看起来是可以的,反正 Scheme 里少说还有『参数顺序求值』
Racket: 4.14.1 Sequences
(define (histogram vector-of-words)Haskell 惰性求值不能保证
(define a-hash (make-hash))
(for ([word (in-vector vector-of-words)])
(hash-set! a-hash word (add1 (hash-ref a-hash word 0))))
a-hash)
duangsuse::Echo
data Maybe a = Just a | Nothing deriving Eq, Show instance Functor Maybe where fmap f (Just x) = Just <$> f x fmap f Nothing = Nothing instance Monad Maybe where return x = Maybe x (Just x) >>= f = f x Nothing >>= _ = Nothing 其中 Fuctor 就是 Functor...…
#FP #CS #Haskell 然后这里有一些 Monad:
+ 这是我从某范畴论教程上抄下来的(虽然完全是我默写下来的...)
+ 使用
+ 如果使用
+ 同构是指有一个
Coproduct: 有
和一个
反过来就是 Product: 比如
从
instance Functor (Either a) where
一般还会有
然后就是 Reader
它的作用就是给一个计算
然后还有推荐的 Cont、ST Monad、Free、Alternative
Cont 就是 CPS Monad
CPS 就是 Continuation Passing Style
比如有一个 Operator
但是可以去 CPS, 假设就有一个
其他的以后我会学的,顺便再学学 Scala 里怎么写... Haskell 是门好语言
newtype Identity a = Identity { runIdentity :: a }
+ Haskell 不会写 Monad 怎么编程?把 Haskell 写成 Scheme?有点困难啊,因为 Haskell 不像 Scheme 还是『有点节操』的函数式(只是组合函数而不是把一切都看成函数组合...)+ 这是我从某范畴论教程上抄下来的(虽然完全是我默写下来的...)
+ 使用
newtype 而不是 data 是因为 Identity 是同构类型+ 如果使用
data 会是这样的:data Identity a = Identity { runIdentity :: a }
data Identity a where
Identity :: a -> Identity a
+ runIdentity :: Identity a -> a 和 Identity 构造器的类型 (Identity :: a -> Identity a) 是同构的+ 同构是指有一个
f :: a -> b 的同时也有 f' :: b -> a
比如说,f = show :: Int -> String; f' = toInt :: String -> Int
这就是说 (f . f') = id = (f' . f)
然后可以去写 Functor Instanceinstance Functor (Identity :: * -> *) where
fmap :: (a -> b) -> (Identity a -> Identity b)
fmap f (Identity i) = Identity <$> f i
这里 i :: a,直接模式匹配把 a 取出来了instance Monad Identity where
return x = Identity x
Identity x >>= f = f x
然后还有比较常用的 Maybe 和 Either 和新学到的 Reader Monaddata Maybe a where... 我还是不知道
Just :: a -> Maybe a
Nothing :: Maybe a
deriving (Eq, Show)
instance Functor (Maybe :: * -> *) where
fmap :: (a -> b) -> (Maybe a -> Maybe b)
fmap f (Just x) = (Just . f) $ x
fmap f Nothing = Nothing
instance Monad Maybe where
return :: a -> Maybe a
return = Just
(>>=) :: Maybe a -> (a -> b) -> b
(Just x) >>= f = f x
Nothing >>= f = Nothing
mu :: t t a -> t a 使用在哪里... 但是 (>>=) 说不定使用了它,因为 f x 是 b,但是 Nothing 是 Maybe a 呢,就是说要先 Map 到 Maybe Maybe a 才用 mu :: Maybe Maybe a -> Maybe a 弄回来就可以了?data Either a b = Left a | Right b deriving (Eq, Show)这里 Either a b 是 a 和 b 的 Product Type
Coproduct: 有
Left 箭头从 a 到达 Either a b ;Right 箭头从 b 到达 Either a b
有一个 (Left :: a -> Either a b) Constructor和一个
(Right :: b -> Either a b ) 构造器反过来就是 Product: 比如
(\(Left l) = l) :: Either a b -> a (这里为了方便没有考虑还有 Right 解构器的事情;实际上这是不对的,导致不是所有 Either 值都能被这个 Operator 解构)从
Either a b 到达 a (箭头就是 (->) Haskell 的中缀类型构造器)instance Functor (Either a) where
fmap _ (Left l) = Left l就是 mapRight
fmap f (Right r) = Rigth $ f r
instance Monad (Either a) where此外,一般还定义这些函数:
Left l >>= f = Left l
Right r >>= f = f r
either :: Either a b -> (a -> a') -> (b -> b') -> Either a' b'好吧... 这好像是 Map 两边的...
either (Left l) f _ = Left $ f l
either (Right r) _ g = Right $ f r
either :: (a -> c) -> (b -> c) -> Either a b -> c其实是
either f g (Left x) = f x
either f g (Right x) = g x
一般还会有
(isLeft :: Either a b -> Bool)、(asLeft :: Either a b -> Maybe a)、swap :: Either a b -> Either b a、flatMapLeft :: Either a b -> (a -> c) -> c 什么的然后就是 Reader
它的作用就是给一个计算
fun :: t -> a 喂一个 t,拿到一个 a
newtype Reader t a = Reader { runReader :: (t -> a) }
这里 runReader :: Reader t a -> (t -> a)
然后我们去 instance Functor 和 Monad 它instance Functor (Reader t) where有点难于理解,看看怎么用的...
fmap f (Reader r) = Reader $ \i -> f (r i)
instance Monad (Reader t) where
return x = Reader (\_ -> x)
(Reader r) >>= f = Reader $ \r' -> runReader r' (f (r r'))
然后还有推荐的 Cont、ST Monad、Free、Alternative
Cont 就是 CPS Monad
CPS 就是 Continuation Passing Style
比如有一个 Operator
add :: Int -> Int -> Int
然后你定义一个 add2 :: Int -> Int
add2 x = add x 2 — x + 2但是就不能进行其他的计算了(不允许嵌套的话),比如
(putStrLn . show) :: a -> IO () 当然在这里 a 是 (Num a) => Context 下但是可以去 CPS, 假设就有一个
excited :: Int -> IO () 的东西add2Cps x = excited (add x 2)计算就可以在
excited 函数里继续其他的以后我会学的,顺便再学学 Scala 里怎么写... Haskell 是门好语言
duangsuse::Echo
#FP #CS #Haskell 然后这里有一些 Monad: newtype Identity a = Identity { runIdentity :: a } + Haskell 不会写 Monad 怎么编程?把 Haskell 写成 Scheme?有点困难啊,因为 Haskell 不像 Scheme 还是『有点节操』的函数式(只是组合函数而不是把一切都看成函数组合...) + 这是我从某范畴论教程上抄下来的(虽然完全是我默写下来的...) + 使用 newtype 而不是 data 是因为 Identity…
接上文
newtype Reader t a = Reader { runReader :: (t -> a) }
instance Functor (Reader t) where
fmap f (Reader r) = Reader $ \i -> f (r i)
instance Monad (Reader t) where
return x = Reader (\_ -> x)
(Reader r) >>= f = Reader $ \r' -> runReader r' (f (r r'))
doHello :: Reader String String
doHello r = asks >>= \s ->
return "Hello " ++ s
hello = runreader doHello "duangsuse"instance Monad (Reader t) where
return :: a -> Reader t a
return x = Reader (\_ -> x)
(>>=) :: Reader t a -> (a -> Reader t b) -> Reader t b
(Reader g) >>= f = Reader $ \x -> runReader (f (g x)) x