张未晨 11:50 monad设计出来,不是为了干什么,没有monad,maybe还是maybe,io还是io,大家都该干嘛干嘛,弄个monad只是为了给有类似行为的东西起个统称的名字而已。。。跟你把飞机和鸟抽象出一个接口叫flyable没有任何区别,怎么就装逼了
宰相小白板 11:51 我看haskell最初的目的是为了monad。看monad是为了用vert.x里面的一个monad实现,用那个monad实现是为了不想callback hell 。我离各位大神还差太远了。现在刚刚学到functor,monad还没有理解。
王旭林 11:51 @张未晨 是的。它不过是种抽象,抽象的还特别好
风哥 11:56 编程这种事情,只要认识ABC都可以去做,只是看你有没有兴趣
风哥 11:57 这话也不是我讲的,很多年前听一个很老的学者说的
风哥 11:58 早期的那些黑客都是一些小孩子,
风哥 12:00 很多人觉得编程是高科技是一种误解
风哥 12:01 所以就觉得小孩子编程很神,其实并不是,很多技艺都是从小学习的,为什绘画、体育、舞蹈都从小孩子学,编程为什么不呢
风哥 12:05 外行一般都会觉得这个好复杂,好难,编程确实很难很复杂,但并不妨碍你去学习,你让我去拉小提琴我也没办法,但是小孩子可以拉得很好
风哥 12:05 我也不会觉得自卑
风哥 12:06 谦虚,不从存在的,这辈子都不可能谦虚
风哥 12:12 我读哲学的,像是哲学家里面天才多了去了,克里普克高中就完成了博士论文,Quine 24岁哈佛博士毕业
工业聚-古映杰 14:06 问个问题 minimum >>= delete
这种写法,怎么理解?
工业聚-古映杰 14:06 >>=
的签名是 m a -> (a -> m b) -> m b
,minimum
和 delete
都是函数
工业聚-古映杰 14:07 把上述写法,换成等价的 do block 是这样的吗?
工业聚-古映杰 14:07
王旭林 14:09 mininum :: M a delete :: a -> Mb
风哥 14:09 不需要 return
风哥 14:10
风哥 14:10 do
和 >>=
的翻译
王旭林 14:12
工业聚-古映杰 14:13 这样 GHC 会报错
余乐 14:13
工业聚-古映杰 14:13
风哥 14:14 那就不需要do
王旭林 14:14 你是怎么定义 Monad的instance的?@工业聚
风哥 14:14 []本身也是Monad
工业聚-古映杰 14:14 用 do 是为了尝试等价表达 minimum >>= delete
王旭林 14:14 是的,[] 本身是Monad的
工业聚-古映杰 14:15 delete (minimum xs) xs
是正常写法
王旭林 14:15 但 minimun >> delete
就得把 [a] -> a
定义为 Monad 才行啊?
工业聚-古映杰 14:15 minimum
不满足 m a
,delete
不满足 a -> m b
,但可以 >>=
组合起来,并且不需要声明 instance
张未晨 14:15 minimum
又不返回 [a]
工业聚-古映杰 14:15
工业聚-古映杰 14:16 这个是全部代码~
风哥 14:16 搞这么复杂干吗 张未晨 14:17 操作list而已,你们确定一定要在do块里做么?
工业聚-古映杰 14:17
工业聚-古映杰 14:17 提问的目的,只是想理解 >>=
怎么把两个函数给整合起来
工业聚-古映杰 14:17 对于解决 removeSmallest
的问题,delete (minimum xs) xs
已经足够
风哥 14:18 函数类型也是 monad
风哥 14:18 这单参数的函数就是 monad 张未晨 14:19 对,这里的 m
是 ->
不是 []
余乐 14:20 这个我也猜到了,就是这个 monad instance 是怎么定义的。
余乐 14:20 难道是 ->
?
风哥 14:20 源码里面有
风哥 14:21 (->) a
风哥 14:25
王旭林 14:28 @Novalis 是的。这家伙好难认啊
王旭林 14:28 得练练才好认出来
王旭林 14:29 minimun :: Ord a => [a] -> a
属于 (v -> ?)
这个Monad
王旭林 14:30 delete :: Eq a => a -> [a] -> [a]
也可理解为 delete :: Eq a => a -> ([a] -> [a])
风哥 14:30 其实 m a
就是结果为 a
的计算 , (->) a
也是一样的理解
风哥 14:31 ((+1) >>= \x -> return x) 1
你看看这个算出来时多少,你就明白了
王旭林 14:32 delete :: Eq a => a -> ([a] -> [a])
中的 ([a] -> [a])
属于 (v -> ? )
这个 Monad 所以 delete 的声明 可以为: delete :: Eq a => a -> M a
王旭林 14:32 这样就符合 (>>=) :: M a -> (a -> M b)
这个了
风哥 14:32 跟他那个 minmum 一样的道理
风哥 14:33 就相当于 (minmum >>= delete)
这整个是一个函数
风哥 14:33 你把 monad 当成一个黑盒,不管他的,但是你知道它需要一个参数,然后计算出一个结果
风哥 14:34 所以传入参数,(minmum >>= delete) [1,2,3]
风哥 14:34 同理你可以把任何这样的函数组合起来组成一个大的黑盒
王旭林 14:35 再说一下细的 minimun :: [a] -> a
相当于 (a -> ?)
这一个Monad 也就是可以写为 minimun :: M a delete:: a -> ([a] -> [a])
相当于 a -> M b
这样 正好符合了: (>>=) :: M a -> (a -> M b)
所以 minimun >>= delete
是合法滴
NullPointerException 14:35 我是把monad看做一个管道,里面是impure的东西 外面是pure的东西…
风哥 14:35 ((+1) >>= (+) >>= (+)) 1
风哥 14:35 你看看这个多好玩,计算结果是多少
风哥 14:36 moand 就可以让你组合这些不同的计算
工业聚-古映杰 14:36
工业聚-古映杰 14:36 我尝试实现了一个 fake >>=
工业聚-古映杰 14:36 这下理解了
风哥 14:36 肯定可以啊
王旭林 14:36 Monad 是种抽象数据结构,看成管道就看扁Monad了
风哥 14:37 只要是单参数的函数都可以
工业聚-古映杰 14:37
夜色残阳 14:37 monad 主要看 >>=
的实现吧,也不是什么黑盒,>>=
不一样,计算传递的方式就不一样,所以才有state/reader/…,所以要理解不同的monad就去看他的定义就好了,而不是在这里猜来猜去
风哥 14:37 其实对于[a]也是一个计算嘛,结果是a的计算,至于[]是啥你不管他的,这就叫抽象
风哥 14:39 任何monad都是这样
风哥 14:39 这不是猜测,这就是monad的本质
风哥 14:40 你只有忽略这些细节你才能从抽象的角度把握monad
风哥 14:41 你掉进细节就上丧失了它的优势
风哥 14:41 就像OO编程讲究接口,都是有意识的做出抽象
风哥 14:42 你的moand的组合就不依赖于具体的实现,你只要保证类型是正确的就可以了
… 14:43 不然你老是去纠结不同 >>=
的实现细节 你一天也写不了多少hs代码
风哥 14:43 写haskell你想得越少就越符合直觉
风哥 14:44 Monad is nothing,这就对了
夜色残阳 14:44 类型正确,只能保证代码能跑起来,不能保证代码一定按我们想法跑起来,不然写Haskell也不用写测试了
风哥 14:45 monad一经证明就不用再去怀疑,逻辑错误往往和monad没啥关系
风哥 14:45 只是你组合的姿势对不对,monad本身还是应该看做黑盒
风哥 14:48 这也是体现了monad的封装性质
风哥 14:50 抽象肯定是有代价的
夜色残阳 14:53 首先要习惯这层抽象,习惯了就好,看见对应的monad,就知道大概是在做什么了,自己要用的时候也一样
余乐
Zete 15:00 习题: ((+1) >>= (+) >>= (\x y z -> x + y + z)) 2 3
等于多少, 为什么 [呲牙]
风哥 15:02 fixed = cos 1 : map cos fixed
haskell最大价值就是美学上的,可以写这么漂亮的代码,再慢有什么关系呢
风哥 15:02 其实比Python什么的还是快很多
Zete 15:52 其实 Python 也不差的 mpmath.findroot(lambda x: cos(x) - x, 1.0)
风哥 15:55 能无限取值吗
风哥 15:55 还是丑
Zete 16:35 Ruby 的思路: number.match?(/\A\d{13,16}\z/) and (*ns, checksum = number.chars.map &:to_i; ns.each_slice(2).flat_map{|n1, n2| (n1 * 2).divmod(10) << (n2 or 0) }.sum * 9 % 10 == checksum)
そら 17:09 只学过Haskell而且只学了一点表示完全看不懂[捂脸]