网页资讯视频图片知道文库贴吧地图采购
进入贴吧全吧搜索

 
 
 
日一二三四五六
       
       
       
       
       
       

签到排名:今日本吧第个签到,

本吧因你更精彩,明天继续来努力!

本吧签到人数:0

一键签到
成为超级会员,使用一键签到
一键签到
本月漏签0次!
0
成为超级会员,赠送8张补签卡
如何使用?
点击日历上漏签日期,即可进行补签。
连续签到:天  累计签到:天
0
超级会员单次开通12个月以上,赠送连续签到卡3张
使用连续签到卡
02月08日漏签0天
linux吧 关注:538,515贴子:2,574,974
  • 看贴

  • 图片

  • 吧主推荐

  • 视频

  • 游戏

  • 56回复贴,共1页
<<返回linux吧
>0< 加载中...

gcd.hy

  • 只看楼主
  • 收藏

  • 回复
  • 8pm
  • ----x-w-
    10
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
@wx_y_am
http://tieba.baidu.com/p/4167457985
有點偏題,還是發這裏吧
圖也搬過來

這個叫 hy,算是 lisp 的方言
http://docs.hylang.org/en/latest/
簡單說就是通過 python 的 import hook,可以運行前將 hy 代碼編譯成 cpython 的 AST,然後再通過 python 本身編譯成 python bytecode 運行。由於在 AST 層級操作,所以提供完整的 macro 支持(當然不是 scheme 的 hygiene)。
可以和 python 無縫結合,即如果安裝了 hy,在 pyhton 裏可以直接 import 用 hy 寫的東西,反過 hy 也可以 import 任何 python 的。
我正在用 hy 寫一個 monad 庫,這是其中一個例子,那時候剛好在測試就截圖了。
這個 gcd 不一樣的地方是,算法是普通的輾轉相除取餘,但整個 gcd 返回的是個 writer monad。也就是 gcd 的 signature (用 haskell 風格描述)是 gcd :: int -> int -> StringWriter string int。其中 StringWriter string 是 writer monad,string 是 monoid。

我另外將相關代碼部分截了圖,左欄是 writer monad 和 execute, tell 的實現,功能和 haskell 的 execWriter, tell 一樣,只不過我利用了 python 的動態類型特性。tell 是將 message 添加到 writer 的累積部分(tuple (result, messages) 的第二部分),execute 是進行這個 writer 運算並將第二部返回,即累積的 message,也就是每次遞歸中 gcd 裏 tell 發送的內容。最後用 print 輸出。
中間是 do-monad 和 do-monad-m 這兩個 macro 的實現,用起來類似 haskell 的 do notation。用來方便寫 monad comprehension。do-monad 和 do-monad-m 的區別是前者會自動增加個 m-return (haskell 裏的 return)call 到結果。所以因爲 gcd 返回的就是 monad,if 的 else 部分遞歸的時候就要用 do-monad-m。
它們和 clojure 的 domonad 類似,不過 clojure 的 monad 不是 boxed 的,而我因爲想在 python 裏支持 >> 作爲 bind(操作符重載),而使用了 class 實現。壞處是這樣寫一些 higher kind 的 monad 很繞,好處是我可以通過附帶的訊息,寫出不需要註明 arity 的 lift 函數。
右上是 monad 的 base class,提供了一些通用操作,其中 join, fmap 和 bind 是相互遞歸的,必須在 subclass 中實現 bind 或者 join, fmap,否則無法直接用。
右下是第一個截圖的 gcd.hy 源碼,方便對應。
這個庫除了 writer,我還實現了 identity, maybe, either, reader, state, continuation,正在整理測試和文檔,弄好了就發出去。


  • 8pm
  • ----x-w-
    10
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
@xw_y_am 不好意思,搞錯 id


2026-02-08 00:40:10
广告
不感兴趣
开通SVIP免广告
  • 8pm
  • ----x-w-
    10
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
葉神

我又寫了一個 writer monad 的例子,這個直接表現了 Writer a 的 a 是個 monoid,比如這個就直接利用了 int 是 monoid 的特性做的加總。用的是 Writer Int Int,因爲我利用 python 的動態,那個 writer 函數會根據 tuple 的第二個值類型創建相應的 writer。
順便因爲寫這個例子,剛剛發現 sequence 的實現由於用 reduce 收集,輸出是倒序的


  • 正义的潘达
  • -----rwx
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
我还处在魔法书肉搏的阶段~前排膜拜8pm...


  • 荆棘的思念
  • ----x-wx
    11
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
我还是没搞明白 Reader Monad 和 Writer Monad是干嘛的


  • 8pm
  • ----x-w-
    10
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
其實荊棘 CPS 都能搞,我很難想象搞不明白 Reader 和 Writer。應該就是指有什麼用吧。
reader monad 等於 partial applied function,剩下一個 environment 參數,或者 shared global state。原意是 read only 的,但是能不能保證就看語言了,比如我寫這個就不能。
一個 ask 就取得整個 env,如果是 mutable 的,比如 object, list, dict 等,改了也就改了。
我寫那個 ssg 原來是用 generator 實現各個步驟,比如列舉源文件,轉換成 html,增加 tags 索引,增加日期檔案,增加 assets,寫入目標目錄,都各自是個 generator,然後 compose 在一起。這樣的 data flow 很好,中間串起來的就是一個 sequence。但是需要讀取一些全局設置,怎麼辦呢,曾經用過 global state (嚴格來說不算,我的實現是個 stack,需要時 import,會 push 一個新的進去,用完 pop,訪問沒有的元素會從下一層找,和 javascript 的 prototype 方式很像,只是沒有用到當前的 thread 來做 hash,所以比 flask 的類似實現低級,即不是 thread-safe 的)。
因爲我一直仍同 stupid data 比較好,而每個 generator 串起來還需要增加一個 env 參數,很麻煩,就想到 monadic 的方案,於是用 python 寫了個,覺得用起來很麻煩。後來看到 hy 比較成熟了(作者第一時間在 pycon 2013 公佈我就知道了,那時候沒有正經看待),於是改用 hy 寫。
writer 也很類似,通過 bind,隱式的增加多一個累計的東西(即 monoid),而使用的 api 不需要看到。
這兩個加上 state monad,基本上都等於幫助實現 composible 的函數(處理步驟)而不需要管顯式的 pass 額外參數,api 更乾淨,而且中間傳遞的 data,也可以是 primitive 的數據類型,比如我那個 ssg 的普通的 sequence。
這些用在對的地方,都很好。當然還是 haskell 類的語言更好:1. 在沒有 tco 的語言中,多個 bind 連起來即多個嵌套調用,效率並不好。2. 沒有強大的類型系統支持,特別是像我這種用動態類型語言的,調試也麻煩。


  • 马三小伙儿
  • ----xr-x
    13
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼


  • MasterRay
  • -----rwx
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
瞻仰……
再開始學 Clojure 後拜讀


2026-02-08 00:34:10
广告
不感兴趣
开通SVIP免广告
  • MasterRay
  • -----rwx
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
前一段時間打算再找一個括號語言撿起來,選擇了 Clojure。看了 Clojure in Action (熟悉語法用),The Joy of Clojure (推薦,比起一般介紹書籍多了大量原理思考,難能可貴)
Clojure 比先驅 Lisp 有很大進步,減少了很多不必要的小括號,還把很多地方換成中括號增加了清晰性。相比與 Java 括號不算多,很多地方可以看作把內斂的括號換到外側了( f(x) -> (f x) if(){} -> (if ))
但是缺乏內置中綴記號感覺很麻煩,描述簡單表達式可讀性非常差
Lisp家族外的大多多數語言語法根植於行、以特定符號分割,結合少量surround操作,編輯就很方便。Lisp則不然,很多語法單元是跨行的(很多地方用到未結束的開括號;類C語言的 { 與之情況類似,但因爲數量少,易定位,編輯尚方便),得靠 paredit/smartparens 等進行語法單元爲單位的編輯操作。找到了一個練習的地方:4clojure.com (好處在於可以看到他人解答,熟悉多種方法。真希望其他語言有類似物),感覺編輯效率還是有差,往FP方向靠又不如 Haskell/OCaml。之前算法題練多了養成了習慣,非常追求編輯效率,看着諸多括號感覺可讀性真欠佳,後來還是沒能繼續學下去……


  • 8pm
  • ----x-w-
    10
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

threading macro 增加易讀性
光標所在行的 set-state 用的 lcg random 算法。
(-> seed (* a) (+ c) (% m))
和讀起來一樣,我覺得在這個情況下比中綴還好讀
最好結果那裏也是
(-> result (get true) (/ number-of-points) (* 4))
result 是個 itertools.Counter object,true 的數量就是在 1/4 圓面積裏的點,然後取比例,乘上 4,和自然語言語序一樣,也是挺好讀的。


  • 幻の上帝
  • ----xrw-
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
看标题还以为是什么河蟹脚本……


  • 烽火戏猪头
  • ----x-wx
    11
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
顶


  • 8pm
  • ----x-w-
    10
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
這個庫已發佈
http://tieba.baidu.com/p/4206002522
或
https://github.com/pyx/hymn/


登录百度账号

扫二维码下载贴吧客户端

下载贴吧APP
看高清直播、视频!
  • 贴吧页面意见反馈
  • 违规贴吧举报反馈通道
  • 贴吧违规信息处理公示
  • 56回复贴,共1页
<<返回linux吧
分享到:
©2026 Baidu贴吧协议|隐私政策|吧主制度|意见反馈|网络谣言警示