`

ludy 0.0.3 released

    博客分类:
  • ruby
阅读更多
睽違已久,忽然心血來潮多加了幾個東西。
in CHANGES:
==============================
ludy 0.0.3, 2007.08.07

1. ludy_ext:
added:
1. Proc#curry
2. Proc#compose
3. Proc#chain
4. Symbol#to_proc
5. Array#foldl
6. Array#foldr
7. Array#filter

removed:
1. Fixnum#collect # see tc_ludy_ext.rb#test_fixnum_collect for reason

info:
1. ruby2ruby has NilClass#method_missing return nil,
so i can't just make it return blackhole

2. module Curry:
see test/tc_curry.rb for usage

see unit test for usage
==============================
雖然說請看 unit test 來揣摩用法,不過這樣真的有點無趣,所以還是來稍微介紹一下。這次之所以忽然心血來潮想做,是因為看到James Edward Gray II 的 higher-order ruby 專欄:
http://blog.grayproductions.net/articles/category/higher-order-ruby
第六篇的:Currying, 他的 curry 實做:
class Proc
def curry(&args_munger)
lambda { |*args| call(*args_munger[args]) }
end
end

老實講,不是說看不懂,可是我不明白為什麼要寫得那麼複雜,乍看之下實在看不太出來。丟掉他的實做,我試著做了一個:
class Proc
def curry *pre
lambda{ |*post| self[*(pre + post)] }
end
end

就我自己測試起來,效果是一樣的,我認為應該簡潔易懂多了。可是這根本不太像 curried function 吧?內心吶喊著。不過在看我後來寫的 curry module 之前,先來簡單介紹一下 currying.

在 lambda caculus 中,每個 function 都只能有一個 argument, 這是因為 lambda caculus 是一種極簡的語言,用來研究某些模型的語言。但是如果 function 只能吃一個 argument, 有很多事是會做不到的。於是我們可以靠著 tuple 把許多的 argument 包成一個 argument, 例如在 Haskell 中,tuple 就是 (1,2,3), 用括號括起來的就是 tuple. 所以上面的 (1,2,3) 是一個有三個值的 tuple, 可以把他視為一個值。

比方說有個 function 叫 power, 像是:power 2, 10 會回傳 1024. uncurried function 就會是 power (2, 10), 他吃一個有兩個元素的 tuple, 吐出一個 1024 的值。可是如果是這樣使用的話,其實是很不方便的。有一個方法可以讓 function 依然只吃一個 argument, 但是又不需要使用 tuple, 可以一個值一個值傳入,那就是 curried function.

在 functional programming 中,function 的地位極高,不管在做什麼事,幾乎都是在操作 function. 這也就是所謂的 higher-order function, 操作 function 的 function, 或是產生 function 的 function 諸如此類。curried function 的效果就是當所吃入的 argument 不足時,他會再吐出另一個 function 去吃其他 argument,直到 argument 足夠時才會吐出結果。

power 2 的回傳會是一個 function, 他記住了 2, 當他再吃一個 argument 後,則會再把 2 拿出來跟 argument 做運算。所以 power 的 type 會是:
power :: Int -> Int -> Int
結合順序是從右邊開始,所以是吃一個 Int, 吐出 (Int -> Int), 也就是吃一個 Int 吐出一個 Int 的 function. 可以想成這樣:

power2 = power 2
result = power2 10
result # => 1024

也就是說,可以把他看成是一個會不斷記憶 argument 的 function. 看看 James Edward Gray II 的範例:
multiply = lambda { |l, r| l * r }
double = multiply.curry { |args| args + [2] }
triple = multiply.curry { |args| args << 3 }

multiply[5, 2] # => 10
double[5] # => 10
triple[5] # => 15
triple["Howdy "] # => "Howdy Howdy Howdy "

所以他的實做其實很簡單,就是用一個 array 記憶 arguments,
最後再 prepend 到最後的 arguments 裡。
class Proc
def curry(&args_munger)
lambda { |*args| call(*args_munger[args]) }
end
end

不過我覺得不用寫得那麼複雜,所以改寫為:
class Proc
def curry *pre
lambda{ |*post| self[*(pre + post)] }
end
end

這裡利用了 ruby 的 lambda 有 closure 的特性,把 *pre 紀錄下來,再把他 prepend 到 post 上,最後再呼叫原本的自己(self)。

可是這樣不完整,因為你必須明確表達你需要做 curry, 而 Haskell 的 curried function 是可以讓你忽略這件事的。

lambda{|a,b,c,d,e|}.curry(1).curry(2).curry(3).curry(4).carry(5)

這樣不煩死才怪。我希望能用:

lambda{|a,b,c,d,e|}[1][2][3][4][5]
也能使用:
lambda{|a,b,c,d,e|}[1,2][3][4,5]

可惜我暫時還沒找到好做法 XD 目前暫時僅提供可以 mixin 的 module, 大概是這樣用:

class Array; include Curry; end

接著 array 所有以字母開頭的 method 會多個 curried 版,prefix c. i.e., map => cmap; foldr => cfoldr

func1 = [1,2,3].cfoldr[:-.to_proc]
assert_equal 2, func1[0]

做法其實很簡單,就只是檢查參數夠了沒,不夠就重新 curry 一份,夠了就呼叫原始 method. 我原本一直不希望前綴 c, 而以相同名字命名之,然後原本的名字改為:orig_method. 可惜不管怎麼試都失敗,原因不是很清楚,但這種 side-effect 超大的動作,會失敗其實也不怎麼奇怪吧,我想。雖然我總覺得以正常呼叫法而言,應該是沒什麼差才對,也許我有哪裡寫錯了,只是還沒發現而已。

*

至於其他新增的東西,這裡也稍微介紹一下。首先 Array#filter 只是 select 的 alias, Array#foldl 也只是 inject 的 wrapper. Array#foldr 稍微複雜些,不過概念上只是類似反過來的 inject 而已。Symbol#to_proc 大家應該都很熟,連 active_support 裡面也有。只是單純的 message/method 轉換而已。

比較需要提的應該是 Proc#compose 和 Proc#chain. 前者就是數學上的 compose, facets 裡其實也有,不過手癢還是自己做了一份。他有點類似反向的 inject, 很容易做出來。至於 chain, 這是模仿 C++ 的 loki 中的 functor 中的 chain. 效果很單純,就是把 function 串起來而已。這拿來做 callback 應該還算方便,例如:

button.on_click = menu.method(:popup).chain button.method(:hide)
接著當按鈕被按下去後,選單就會彈出,且按鈕自動隱藏。
至於 arguments 和 returns 呢?arguments 會統一給所有人。
f1.chain(f2)['XD']
這樣 f1 和 f2 都會接到 'XD' 這個 argument. return 則會蒐集成一個 array 並 flatten 回去。
[f1 的結果, f2 的結果, f3 的結果,...]
如果 f3 的結果是 array, 則會依序儲存:
[..., f3 的結果1, f3 的結果2, f4 的結果, ...]

這樣做的原因是要讓 chain 還能繼續 chain 而不會出現非常恐怖的 nested array.
f1.chain(f2).chain(f3).chain(f4)
但是其實可以這樣 chain:
f1.chain(f2, f3, f4)
結果和上面的會是相同的。

在 chain 之間的 travel 還沒做,下次有機會時會做。

gem install ludy # to see detail

ruby 寫起來真的很簡潔,很多功能 10 行內都能解決。

2007.08.07
分享到:
评论

相关推荐

    AppleScript

    AppleScript是一种英语般的脚本语言,易于理解和学习,它被内置在每个Mac操作系统中。使用AppleScript可以自动化数百个苹果可脚本化应用程序,无论是大型还是小型任务,复杂还是简单,都可以执行。...

    java项目,课程设计-ssm病人跟踪治疗信息管理系统

    病人跟踪治疗信息管理系统采用B/S模式,促进了病人跟踪治疗信息管理系统的安全、快捷、高效的发展。传统的管理模式还处于手工处理阶段,管理效率极低,随着病人的不断增多,传统基于手工管理模式已经无法满足当前病人需求,随着信息化时代的到来,使得病人跟踪治疗信息管理系统的开发成了必然。 本网站系统使用动态网页开发SSM框架,Java作为系统的开发语言,MySQL作为后台数据库。设计开发了具有管理员;首页、个人中心、病人管理、病例采集管理、预约管理、医生管理、上传核酸检测报告管理、上传行动轨迹管理、分类管理、病人治疗状况管理、留言板管理、系统管理,病人;首页、个人中心、病例采集管理、预约管理、医生管理、上传核酸检测报告管理、上传行动轨迹管理、病人治疗状况管理,前台首页;首页、医生、医疗资讯、留言反馈、个人中心、后台管理、在线咨询等功能的病人跟踪治疗信息管理系统。在设计过程中,充分保证了系统代码的良好可读性、实用性、易扩展性、通用性、便于后期维护、操作方便以及页面简洁等特点。

    liunx project 5

    liunx project 5

    PostgreSQL DBA实战视频教程(完整10门课程合集)

    分享课程——PostgreSQL DBA实战视频教程(完整10门课程合集)

    计算机科学基础期末考试试题

    计算机科学基础期末考试试题

    c语言实验设备管理系统

    练习与巩固《C语言程序设计》理论知识,通过实践检验和提高实际能力,进一步培养自己综合分析问题和解决问题的能力。掌握运用C语言独立地编写调试应用程序和进行其它相关设计的技能。

    提高图像在低光照条件下的清晰度和可见性,使用CNN的图像重建网络,来实现亮度调节,可用于小白学习

    1. 数据集资源 公开低光照数据集:用于模型训练的低光照图像数据集,这些数据集包含了多种低光照条件下的图像,并附有增强后的高质量图像。 合成数据:在不足数据的情况下,可以通过对高亮度图像进行暗化处理生成低光图像对,以增强数据量。 自建数据集:对于特定场景,如安防、医疗等,可以拍摄或收集特定条件下的低光照图像来创建数据集,满足特定应用需求。 2. 硬件资源 GPU:大规模模型训练需要高性能计算,以支持大规模图像处理和神经网络训练。 数据存储:由于图像数据较大,需要大容量的存储设备如HDD或SSD来存储数据集及中间结果。 3. 深度学习框架及工具 PyTorch:支持构建和训练神经网络模型,尤其适合卷积神经网络(CNN)和生成对抗网络(GAN)的实现。 CUDA和cuDNN:为GPU加速库,在模型训练时可显著提升运行效率。

    双哥微服务.md

    双哥微服务

    fb000f5e-12c5-a46b-102a-f08bdfa015f1.json

    fb000f5e-12c5-a46b-102a-f08bdfa015f1.json

    C#ASP.NET跑腿服务网站源码数据库 Access源码类型 WebForm

    ASP.NET跑腿服务网站源码 开发环境 :Asp.net + VS2010 + C# + ACCESS 网站介绍: 适合人群:跑腿服务行业公司,服务资讯公司或者其他行业企业、 做服务行业建站的技术人员、技术人员学习参考都行。 技术特点:非常清爽大气的网站,界面华丽,工整,采用全div布局, 含flash图片切换功能,强大的后台信息管理功能。 功能介绍: 后台功能:系统参数设置(网站标题,关键字,内容,站长联系方式等)、系统栏目频道设置、新闻管 理、服务项目管理、公司介绍内容管、系统模版管理(可管理前台页面模版内容,具体到头部页面,底 部页面,首页,内容页,新网页等)、系统日志管理、系统管理员管理、频道管理(频道类型、频道内 容、内容发布以及编辑)。 后台地址:网址/admin/login.aspx 账户:admin 密码:admin888

    KCP一个快速可靠的ARQ协议.zip

    c语言

    【小程序毕业设计】基于微信小程序的物流运输(仓储)系统开发与设计源码(完整前后端+mysql+说明文档+LW).zip

    环境说明: 开发语言:Java/php JDK版本:JDK1.8 数据库:mysql 5.7及以上 数据库工具:Navicat11及以上 开发软件:eclipse/idea 小程序框架:uniapp/原生小程序 开发工具:HBuilder X/微信开发者

    计算机中 人工智能的七大应用领域

    人工智能(Artificial Intelligence,缩写为AI)是一种通过计算机程序模拟人类智能与行为的技术和理论。它可以用于各种领域,例如:自动驾驶、机器翻译、语音识别、图像识别、医疗诊断等。近年来,人工智能逐渐成为了技术界和商业领域的热门话题。

    ESP32ESP32C2ESP32C3ESP32C6ESP8266的AT应用.zip

    c语言

    基于JAVA实现的离散数学题库管理系统.zip

    基于JAVA实现的离散数学题库管理系统

    【图像压缩】基于matlab GUI低比特率图像压缩(含比特率 压缩包 信噪比)【含Matlab源码 9132期】.mp4

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    (源码)基于C++的MiniSQL数据库系统.zip

    # 基于C++的MiniSQL数据库系统 ## 项目简介 MiniSQL是一个轻量级的关系型数据库管理系统,旨在提供基本的SQL解析和执行功能。该项目参考了CMU15445 BusTub框架,并在其基础上进行了修改和扩展,以兼容原MiniSQL实验指导的要求。MiniSQL支持缓冲池管理、索引管理、记录管理等核心功能,并提供了简单的交互式SQL解析和执行引擎。 ## 项目的主要特性和功能 1. 缓冲池管理实现了一个高效的缓冲池管理器,用于缓存磁盘上的数据页,以提高数据访问速度。 2. 索引管理支持B+树索引,提供高效的插入、删除和查找操作。 3. 记录管理实现了记录的插入、删除、更新和查询功能,支持持久化存储。 4. 元数据管理提供了表和索引的元数据管理功能,支持持久化存储和检索。 5. 并发控制实现了基本的锁管理器,支持事务的并发控制。 6. 查询执行提供了简单的查询执行引擎,支持基本的SQL语句解析和执行。 ## 安装使用步骤

    社会科学研究Top 10,000 Papers数据解析论文名称被引次数下载次数等

    社会科学研究Top 10,000 Papers数据解析被引次数下载次数等 一、数据背景与来源 该数据集来源于SSRN(Social Science Research Network)的社会科学研究Top 10,000 Papers,是根据多种学术影响力指标统计得出的,在其平台上最受关注的前10,000篇学术论文的汇总。这些数据反映了国际研究领域的热点话题和发展趋势,对于国内学者研究者来说,是了解社科领域研究进展的重要窗口。 二、数据内容概览 样本数量:数据集包含10,000条记录,每条记录代表一篇在SSRN平台上具有高影响力的学术论文。 论文范围:涵盖社会科学研究的各个领域,包括但不限于经济学、政治学、社会学、心理学、教育学等。 关键指标: 数据下载次数:反映了论文的受欢迎程度和研究者对其内容的关注度。 引用次数:体现了论文在学术界的认可度和影响力,是评估论文质量的重要指标之一。 Rank Paper Total New Downloads Total # of Downloads Total # of Citations # of Authors

    【北京理工大学-2024研报】中国碳达峰碳中和时间表与路线图研究.pdf

    行业研究报告、行业调查报告、研报

    基于 Java+Mysql 实现的企业人事管理系统【课程设计/毕业设计】(源码+设计报告)

    【作品名称】:基于 Java+Mysql 实现的企业人事管理系统【课程设计/毕业设计】(源码+设计报告) 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【项目介绍】: [1]管理员可以对员工的基本信息的增删改查,普通员工仅可查看; [2]对公司里所有员工进行分配工号,并进行基本信息的录入; [3]对新聘用的员工,将其信息加入到员工档案记录中; [4]对于解聘的员工,将其信息从员工档案记录中删除。 [5]当员工信息发生变动时,修改员工档案记录中相应的属性。 (三)员工岗位信息管理 [1]对公司里所有员工的职务及岗位信息(岗位职责)进行记录; [2]记录员工调动前后的具体职务,以及调动时间。 (四)考勤管理 [1]对员工上班刷卡的记录进行统一编号;登记员工上班时间(准时、迟到)。 [2]对员工下班刷卡的记录进行统一编号;登记员工下班时间(准时、早 【资源声明】:本资源作为“参考资料”而不是“定制需求”,代码只能作为参考,不能完全复制照搬。需要有一定的基础看懂代码,自行调试代码并解决报错,能自行添加功能修改代码。

Global site tag (gtag.js) - Google Analytics