在前一篇日志,
将Comiket物的文件名格式统一化的脚本,有这样的回复:
CloudiDust 写道
好想法……去用Groovy或者F#写一个……
其实我没有收Comiket物的习惯啊似乎……我真是没有娱乐的人啊……(望天)
既然Ruby的简单版和C#的版本都写了,写个F#版来对比一下也不错。
下面的程序逻辑基本上与前一篇的C#版类似,只是在如何抽取出文件名中的各部分的实现用了不同的划分方式:C#版的TryGetRenameName()方法更倾向于直接支持不同的pattern和format;F#版则是直接把pattern和format硬编码到parseFilename和getReformattedFilename函数里了。到底该怎么划分好我也不太肯定,不过在这么小的程序里划分方式好不好体现不出来,或许也不值得多想吧?
ReformatComiketFilenames.fsx
#light
open System
open System.IO
open System.Text.RegularExpressions
let parseFilename name =
let result = Regex.Match(name, @"^\(([^)]+)\)\s*\(([^)]+)\)\s*\[([^\]]+)\]\s*(.+)$")
let success = result.Success
let comiketNum = result.Groups.Item(1).Value
let contentType = result.Groups.Item(2).Value
let circleName = result.Groups.Item(3).Value
let itemName = result.Groups.Item(4).Value
success, comiketNum, contentType, circleName, itemName
let getReformattedFilename name =
let success, comiketNum, contentType, circleName, itemName = parseFilename name
if success then
sprintf "(%s)(%s)[%s] %s" comiketNum contentType circleName itemName
else name
let reformatAndRenameDir (dirInfo : DirectoryInfo) =
let name = dirInfo.Name
let destName = getReformattedFilename name
if name <> destName then
printfn "%s" destName
dirInfo.MoveTo(Path.Combine(dirInfo.Parent.FullName, destName))
true
else false
let reformatAndRenameFile (fileInfo : FileInfo) =
let name = fileInfo.Name
let destName = getReformattedFilename name
if name <> destName then
printfn "%s" destName
fileInfo.MoveTo(Path.Combine(fileInfo.DirectoryName, destName))
true
else false
let getRootDir = fun () ->
#if COMPILED
let args = Environment.GetCommandLineArgs ()
#else
let args = fsi.CommandLineArgs
#endif
let rootPath =
match args with
| [| _ |] -> new DirectoryInfo(Environment.CurrentDirectory);
| _ -> new DirectoryInfo(args.[1])
rootPath
let main = fun () ->
let root = getRootDir ()
Array.iter (fun dir -> (reformatAndRenameDir dir; ())) (root.GetDirectories())
Array.iter (fun file -> (reformatAndRenameFile file; ())) (root.GetFiles())
main ()
F#的类型推导对.NET类型的支持还不是很好。let绑定的话,总是能从等号右手边的表达式判断出类型,这跟C#的var的实现其实是相似的。问题主要是函数的参数类型的推导。C#也有方法参数的类型推导问题(特别是在使用lambda表达式的时候),但C#的类型推导相对ML的弱很多。F#对内置类型能做比较好的推导,主要是因为内置类型的信息比较容易获取吧?.NET类型要用同样的推导方式太难实现了。
例如说看到
let succ x = x + 1
的时候,因为F#/OCaml默认+的的参数是int,所以很容易推导出x的类型是int,返回值类型也是int,于是succ的类型就是int -> int。
但如果是一个.NET类型:
let printName (fileInfo : FileInfo) =
printfn "%s" fileInfo.Name
光凭fileInfo.Name这个属性访问,不足以提供fileInfo的类型信息。.NET类型不支持结构等价,结构相同的两个类在是不会被认为是同一个类型的:
class Foo { public string Name { get; set; } }
class Bar { public string Name { get; set; } }
这样的Foo与Bar虽然结构相同,但类型并不相等价。所以很明显,只有一个属性访问为条件,只能告诉F#的类型推导器“哪些类型肯定不满足条件”,却很难说明“哪个类型就是我们要找的类型”。F#的小组似乎在改进F#的类型推导器来改善对.NET类型的支持,不知道他们是怎么做的呢。
话说上面的代码里有这么一小段:
Array.iter (fun dir -> (reformatAndRenameDir dir; ())) (root.GetDirectories())
这里的括号其实挺无奈的……
我本来是想reformatAndRename*这两个函数应该返回些什么值,假如调用方想知道到底有没有做重命名,应该有办法知道。但最后我调用这两个函数的时候没有用到它们的返回值。Array.iter(和List.iter等)函数却对此不高兴了,非要第一个参数返回unit类型而不能是其它类型。所以这里的匿名函数只能写成(fun dir -> (reformatAndRenameDir dir; ()))了。写成这样能正确运行,不过F#的解释器会扔出一个警告说前一个子表达式应该返回unit类型而这里返回的是bool类型。嘛,警告就警告,不管了……
不过后来发觉括号多是我自己的问题而不是F#的问题……T T
这样写就好了:
Array.iter (fun dir -> reformatAndRenameDir dir |> ignore) (root.GetDirectories())
其中ignore是标准库里的函数,内容跟CloudiDust提到的fun x -> ()是一样的。
分享到:
相关推荐
标题中的“将Comiket物的文件名格式统一化的脚本”指的是一个专门用于整理Comiket(同人志活动)相关文件的程序。Comiket是日本最大的同人文化盛会,参与者会发布大量自制的漫画、音乐和其他作品。由于众多创作者...
我还想尝试引入一个管理区域,以更好的方式添加发行版,也许用户支持将发行版标记(甚至添加)作为最终游戏。 我想做的另一件事是确保其背后有一个不错的API,如果任何人想要访问数据,任何人都可以使用。原料药...
函数中添加右键单击菜单以搜索在浏览器上选择的字符串Comiket Web目录它是一个扩展名。 圆形名称,yomigana和作者姓名是针对性的。 如果有1个搜索结果,请自动移动到圆圈详细信息页面。 Comiket Web目录帐户并登录是...
免费的防止锁屏小软件,可用于域统一管控下的锁屏机制
内容概要:本文介绍了一段简单的Python代码,用于在控制台中输出一棵带有装饰的圣诞树。具体介绍了代码结构与逻辑,包括如何计算并输出树形的各层,如何加入装饰元素以及打印树干。还提供了示例装饰字典,允许用户自定义圣诞树装饰位置。 适用人群:所有对Python编程有一定了解的程序员,尤其是想要学习控制台图形输出的开发者。 使用场景及目标:适用于想要掌握如何使用Python代码创建控制台艺术,特别是对于想要增加节日氛围的小项目。目标是帮助开发者理解和实现基本的字符串操作与格式化技巧,同时享受创造乐趣。 其他说明:本示例不仅有助于初学者理解基本的字符串处理和循环机制,而且还能激发学习者的编程兴趣,通过调整装饰物的位置和树的大小,可以让输出更加个性化和丰富。
白色大气风格的设计师作品模板下载.zip
电商平台开发需求文档.doc
白色简洁风格的办公室室内设计门户网站模板下载.zip
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于计算机科学与技术等相关专业,更为适合;
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于计算机科学与技术等相关专业,更为适合;
课程设计---基于Android stduio的手机银行开发与设计 现今,手机已经成为人们生活和工作的必备品,在手机各种系统中Android系统是人们用的比较多的系统。手机银行也是人们在生活中比较常用的功能之一。本项目基于Android的手机银行开发与设计主要功能有登录注册、转账、转账记录查询、修改及查询个人信息、添加好友、向好友转账的功能。本项目主要用Android Studio 开发,数据库SQLite数据库,和夜神模拟器。 基于Android stduio的手机银行开发与设计项目主要功能有登录注册、转账、转账记录查询、修改及查询个人信息、添加好友、向好友转账的功能。。内容来源于网络分享,如有侵权请联系我删除。另外如果没有积分的同学需要下载,请私信我。
白色大气风格的婚礼现场倒计时模板下载.zip
轮式移动机器人轨迹跟踪的MATHLAB程序,运用运动学和动力学模型的双闭环控制,借鉴自抗扰控制技术结合了非线性ESO,跟踪效果良好,控制和抗扰效果较优,可分享控制结构图。 这段程序主要是一个小车的动力学仿真程序,用于模拟小车在参考轨迹下的运动。下面我将对程序进行详细的分析解释。 首先,程序开始时使用`clear`、`clc`和`close all`命令来清除工作空间、命令窗口和图形窗口中的内容。 接下来,程序定义了一系列参数和变量,用于设置仿真的参数和存储仿真过程中的数据。这些参数包括小车的质量、车宽、驱动轮半径等,还有参考轨迹的振幅和频率,仿真步长,仿真时间等。 然后,程序定义了一些元胞数组,用于存储不同阶段的数据。这些数组包括参考轨迹位姿、真实运动轨迹位姿、参考轨迹一阶导数、参考轨迹速度、期望速度、真实速度、控制器输出的控制力矩、控制输入、期望速度与真实速度误差、摩擦值、外界扰动值、总扰动、位姿跟踪误差、扰动观测值等。 接下来,程序给这些变量赋初始值,包括小车的初始位姿和速度,初始速度,期望初始速度,控制器输出的控制力矩,扰动观测值等。 然后,程序进入一个循环,仿真时间从
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于计算机科学与技术等相关专业,更为适合;
这是一份来自开源的全球新冠肺炎数据集,每日时间序列汇总,包括确诊、死亡和治愈。所有数据来自每日病例报告。数据持续更新中。 由于数据集中没有美国的治愈数据,所以在统计全球的现有确诊人员和治愈率的时候会有很大误差,代码里面先不做这个处理,期待数据集的完善。
白色大气风格的时装设计公司模板下载.zip
白色大气风格的商务会议活动模板下载.rar
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于计算机科学与技术等相关专业,更为适合;
本次开发一套基于微信小程序的生签到系统,有管理员,教师,学生三个角色。管理员功能有个人中心,学生管理,教师管理,签到管理,学生签到管理,班课信息管理,加入班课管理,请假信息管理,审批信息管理,销假信息管理,系统管理。教师和学生都可以在微信端注册和登录,教师可以管理签到信息,管理班课信息,审批请假信息,查看学生签到,查看加入班级,查看审批信息和销假信息。学生可以查看教师发布的学生签到信息,可以自己选择加入班课信息,添加请假信息,查看审批信息,进行销假操作。基于微信小程序的生签到系统服务端用Java开发的网站后台,接收并且处理微信小程序端传入的json数据,数据库用到了MySQL数据库作为数据的存储。
**脚本描述**:本脚本围绕着新年这个充满欢乐与希望的时刻展开。故事发生在一个热闹的小镇,主要角色有在外打拼多年的年轻人小李,他的父母,以及一群充满活力的小镇居民。新年将至,小李踏上回家的旅途,满心期待与家人团聚。在小镇上,大家都在积极筹备新年,贴春联、挂灯笼、准备年夜饭。小李与家人重逢后,一起分享着彼此的故事和喜悦。同时,他们也和小镇居民一起举办了热闹的庆祝活动,在欢声笑语中迎接新年的到来。这个新年不仅让小李重新感受到了家的温暖,也让他对未来充满了信心和希望,他决定和小镇一起成长发展。通过这个脚本,展现新年带给人们的幸福、温暖和对未来的憧憬。