格式化是一个类型安全且灵活的库,用于格式化内置或自定义数据类型中的文本。
- 黑客文档
- 介绍图书馆的原始博客帖子,但请注意,某些类型已更改:
洞
不再使用,并且格式
的类型已更改为newtype格式ra=格式{runFormat::(Builder->r)->a}
用法
您可能需要重载字符串
语言扩展,并导入格式化
:
{-#LANGUAGE重载字符串#-}导入格式
您可能还需要以下部分或全部内容:
导入合格数据。文本为T导入合格数据。文本。懒惰如TL导入合格数据。文本。懒惰。建造商作为TLB
现在举一个简单的例子:
>格式(“人名为”%text%“,年龄为”%int“)”Dave“54“此人的名字是Dave,年龄是54岁”
在本例中,格式化程序是两个字符串文字(不带参数)和两个格式化程序(带参数):文本
,这需要一个懒惰文本
、和整数
这需要任何完整的
,例如国际
.它们都使用%
运算符,生成一个接受两个参数的格式化程序:lazy文本
和一个完整的
.它会产生懒惰文本
,因为我们使用格式
.要生成其他字符串类型或打印结果,请参阅下表:
要打印值,请参阅下表:
除了%
运算符,也可以使用monoid append运算符连接格式化程序(<>
)为了避免重复相同的参数,可以使用%.
还有用于组合更高级组合符的格式化组合符。下面是关于这个的更多信息。
内置格式化程序:
要格式化 |
例如 |
作为 |
使用 |
缩写形式 |
懒惰的文本 |
“你好” |
“你好” |
文本 |
吨 |
严格的文本 |
“世界!” |
“世界!” |
文本 |
标准 |
字符串 |
“再见” |
“再见” |
一串 |
秒 |
建设者 |
“浴缸” |
“浴缸” |
建设者 |
|
显示a=>a |
[1, 2, 3] |
"[1, 2, 3]" |
显示 |
什 |
字符 |
'!' |
"!" |
烧焦 |
c(c) |
积分a=>a |
23 |
"23" |
整数 |
d日 |
实a=>a |
123.32 |
"123.32" |
浮动 |
平方英尺 |
实a=>a |
123.32 |
“123.320” |
固定的 三 |
(f) |
科学 |
科学60221409 16 |
“6.0221409e23” |
科学情报局 |
|
科学 |
科学60221409 16 |
“6.022e23” |
scifmt公司 指数(仅3) |
|
可构建n,积分n=>n |
123456 |
"12.34.56" |
组Int 2 '.' |
|
可构建n,积分n=>n |
12000 |
"12,000" |
逗号 |
|
积分n=>n |
32 |
“第32位” |
单词 |
|
数量a,等式a=>a |
1 |
“1只蚂蚁” |
整型<> 复数的 “蚂蚁”“蚂蚁” |
|
数量a,等式a=>a |
2 |
“两只蚂蚁” |
整型<> 复数的 “蚂蚁”“蚂蚁” |
|
枚举a=>a |
一 |
"97" |
asInt公司 |
|
积分a=>a |
23 |
"10111" |
垃圾箱 |
b条 |
积分a=>a |
23 |
“0b10111” |
前缀Bin |
|
积分a=>a |
23 |
"27" |
十月 |
o个 |
积分a=>a |
23 |
“0o27” |
前缀十月 |
|
积分a=>a |
23 |
"17" |
十六进制 |
x个 |
积分a=>a |
23 |
“0x17” |
前缀十六进制 |
|
积分a=>a |
23 |
"13" |
基础 20 |
|
可构建a=>a |
10 |
" 10" |
左边 4 ' ' |
我 |
可构建a=>a |
10 |
"10 " |
正确的 4 ' ' |
第页 |
可构建a=>a |
10 |
“10” |
中心 4 ' ' |
|
可构建a=>a |
123456 |
"123" |
fit左侧 三 |
|
可构建a=>a |
123456 |
"456" |
fit右侧 三 |
|
可构建a=>a |
真的 |
“正确” |
建造 |
|
一 |
未定义 |
“哼!” |
fconst公司 “哼!” |
|
格式化程序组合器采用格式化程序并以某种方式对其进行修改,例如使用它来格式化列表的元素,或更改其输出。
内置格式化程序组合器:
要格式化 |
例如 |
作为 |
使用 |
也许是一个 |
什么都没有 |
“再见” |
五月床 “再见”文本 |
也许是一个 |
只是“你好” |
“你好” |
五月床 “再见”文本 |
也许是一个 |
什么都没有 |
"" |
有选择权的 文本 |
也许是一个 |
只是“你好” |
“你好” |
有选择权的 文本 |
要么a b |
左“错误!” |
“错误!” |
艾瑟德 文本int |
要么a b |
右69 |
“69” |
艾瑟德 文本int |
要么是x |
左“宾果” |
“宾果” |
左撇子 文本 |
要么是x |
右16 |
"" |
左撇子 文本 |
x或a |
右“宾果” |
“宾果” |
有权利的 文本 |
x或a |
左16 |
"" |
扶正的 文本 |
可折叠t=>t a |
[1, 2, 3] |
“第二第三” |
串联的 单词 |
可折叠t=>t a |
[123456789] |
"789456123" |
加入 (mconcat.reverse)整数 |
可折叠t=>t a |
[1, 2, 3] |
"1||2||3" |
插层的 “||”整数 |
可折叠t=>t a |
[1, 2, 3] |
"1 2 3" |
未装备的 整数 |
可折叠t=>t a |
[1, 2, 3] |
“1\n2\n3” |
无衬里的 d日 |
可折叠t=>t a |
[1, 2, 3] |
"1 2 3" |
间隔 整数 |
可折叠t=>t a |
[1, 2, 3] |
"1,2,3" |
逗号步骤 整数 |
可折叠t=>t a |
[1, 2, 3] |
“第一、第二、第三” |
通信空间分离器 单词 |
可折叠t=>t a |
[“一”、“二”、“三”] |
“[一,二,三]” |
列表 吨 |
可折叠t=>t a |
[“一”、“二”、“三”] |
“[”一“,”二“,”三“]” |
qlist(qlist) 吨 |
【a】 |
[1..] |
“[1,10,11,100]” |
拿 4(列表箱) |
【a】 |
[1..6] |
"[4, 5, 6]" |
下降 3(列表int) |
一 |
“一个二个三个” |
“一、二、三、四” |
溅射 isSpace commaSpaceSep文本 |
一 |
1234567890 |
"[123, 456, 789, 0]" |
splotWith(使用) (chunksOf 3)列表int |
一 |
“一、二、三” |
“一棵树\n两棵树\n” |
飞溅 “,”无衬里t |
一 |
“一二三” |
“[一,二,三]” |
措辞的 列表文本 |
一 |
“”一棵树\n\n两棵树\n\n“ |
“[”一“,”二“,”三“,”]“ |
有内衬的 qlist文本 |
一 |
123456 |
"654321" |
更改为 TL.reverse整数 |
一 |
“数据.Char.isUpper |
“DCU” |
字符保留If 是上部字符串 |
一 |
“数据.Char.isUpper |
“ata.har.ispper” |
删除的字符If 是上部字符串 |
一 |
“外观和引导” |
“韭菜和甜菜” |
替换 “oo”“ee”文本 |
一 |
“外观和靴子” |
“外观和靴子” |
大写的 |
一 |
“外观和引导” |
“外观和引导” |
小写的 |
一 |
“外观和引导” |
“外观和引导” |
有标题的 |
一 |
“你好” |
“他……” |
超短的 5个文本 |
一 |
“你好” |
“高…s” |
无套管的 |
一 |
“你好” |
“…os” |
rtruncated(已运行) 5个文本 |
一 |
1 |
" 1" |
添加了lp 3整型 |
一 |
1 |
"1 " |
rp已添加 3整型 |
一 |
1 |
" 1 " |
cpadded(已添加) 3分 |
一 |
123 |
"123 " |
lfixed公司 4整型 |
一 |
123456 |
"1..." |
lfixed公司 4整型 |
一 |
123 |
" 123" |
固定的 4整型 |
一 |
123456 |
“…6” |
固定的 4整型 |
一 |
123 |
" 123 " |
cfixed(固定) 2 1英寸整数 |
一 |
1234567 |
"12...7" |
cfixed(固定) 2 1英寸整数 |
一 |
“咕” |
“McGoo” |
加了前缀 “Mc”t |
一 |
“咕” |
“古森” |
后缀 “sen”t |
一 |
“咕” |
“McGooMc” |
包围 “Mc”t |
一 |
“咕” |
“麦库森” |
随函附上的 “Mc”“sen”t |
一 |
“咕” |
“‘咕’” |
方形的 吨 |
一 |
“咕” |
“\”顾\“” |
d引用 吨 |
一 |
“咕” |
“(咕)” |
带括号的 吨 |
一 |
“咕” |
“[顾]” |
平方的 吨 |
一 |
“咕” |
“{Goo}” |
有支撑的 吨 |
一 |
“咕” |
“<顾>” |
有角度的 吨 |
一 |
“咕” |
“`Goo`” |
反勾选的 吨 |
一 |
“咕” |
“咕” |
缩进的 3吨 |
可折叠t=>t a |
[1, 2, 3] |
“1\n 2\n 3” |
缩进的线条 2天 |
一 |
“1\n2\n3” |
“1\n 2\n 3” |
重新凹陷 2吨 |
积分i,RealFrac d=>d |
6.66 |
"7" |
舍入到 整数 |
积分i,RealFrac d=>d |
6.66 |
"6" |
截断到 整数 |
积分i,RealFrac d=>d |
6.66 |
"7" |
天花板收件人 整数 |
积分i,RealFrac d=>d |
6.66 |
"6" |
地板至 整数 |
通过字段镜头是一个 |
(1,“好”) |
“咕” |
已查看 _2吨 |
字段通过记录访问器s->a |
(1,“好”) |
"1" |
已访问 fst日期 |
积分a=>a |
4097 |
“0b00010000000000001” |
bin前缀 16 |
积分a=>a |
4097 |
“0亿0000000000010001” |
octPrefix(八位前缀) 16 |
积分a=>a |
4097 |
“0x0000000000001” |
十六进制前缀 16 |
序f,积分a,分数f=>a |
1024 |
“1KB” |
字节 最短的 |
序f,积分a,分数f=>a |
1234567890 |
“1.15GB” |
字节 (固定2) |
%.
就像是%
但将一个格式化程序输入到另一个:
λ> 格式(左2'0'%.1hex)10“0a”
λ> 现在<-getCurrentTimeλ> 格式(年份%“/”<>月份<>“/”%dayOfMonth)现在"2015/01/27"
可构建类型类
关于格式化
它不依赖于类型类:您可以为每个类型定义一个或多个格式化程序。但您也可以通过实现可构建
typeclass,它有一个方法:构建::p->生成器
.一旦为类型定义了这一点,就可以使用建造
格式化程序(与建造
方法可构建
!):
>format(“Int:”%build%“,Text:”%build)23“你好”“Int:23,Text:hello”
请注意,虽然这可能很方便,但也牺牲了一些类型安全性:没有什么可以阻止您将参数按错误的顺序排列,因为这两者都是国际
和文本
有一个可构建
实例。还要注意,如果一个类型已经有显示
实例,则可以使用展示
格式化程序。
了解类型
格式化程序通常具有如下类型:
格式r(a->r)
这描述了最终将生成某些字符串类型的格式化程序第页
,并接受一
作为一个论点。例如:
int::积分a=>格式r(a->r)
这需要一个积分a
论点,并最终产生第页
.让我们将此与一起使用格式
:
--格式具有以下类型:format::格式化TL.Text a->a--因此,在“format int”(用“int”调用)中,“int”的类型专门用于:int::设置TL.Text格式(int->TL.Text)--和“format's”a“参数专门用于“Int->TL.Text”:格式::设置TL.Text格式(Int->TL.Text)->Int->TL.Text--因此,“format int”采用int并生成文本:格式int::int->TL.Text
上面可能令人困惑的是整数
的一
参数展开为国际
,但是格式
的一
参数展开为Int->TL.文本
.
现在让我们看看使用%
附加格式化程序的运算符:
--以下是我们将使用的函数类型:(%)::格式ra->格式r->格式rint::格式r(int->r)--对此进行了简化stext::格式r(T.Text->r)--在对“%”的调用中,在表达式“int%stext”中,类型参数展开如下:--r=T.文本->r'--a=Int->T.文本->r’--因此我们有以下类型:int::格式(T.Text->r')(int->T.Text->r')stext::格式r'(T.Text->r')int%stext::格式r'(int->T.Text->r')--因此,当我们使用“format”时,我们会得到一个函数,它接受两个参数并生成文本:格式(int%stext)::int->T.Text->TL.Text
与其他语言的比较
例子:
格式(“人名为”%text%“,年龄为”%hex“)”Dave“54
或使用短名称:
格式(“人名为”%t%“,年龄为”%x“)”Dave“54
类似于C打印
:
printf(“人名为%s,年龄为%x”,“Dave”,54);
和通用Lisp格式
:
(格式为nil“人名为~a,年龄为~x”“Dave”54)
“你好,世界!”:短信
>format(text%“!”)“你好!”“嗨!!”>format(string%“!”)“你好!”“嗨!!”
123:整数
>格式int 23"23"
23.4:小数
>格式(固定为0)23.3“23”>格式(固定2)23.3333"23.33">最短格式23.3333"23.3333">格式最短0.0"0.0">sci 2.3格式"2.3">格式(scifmt固定(仅0))2.3"2"
1242:逗号
>格式逗号123456778"123,456,778">格式逗号1234"1,234"
第一:序号
>格式化单词1“第一个”>格式化单词2“第二”>格式化单词3“第三”>格式化单词4“第四名”
3F:六角
>格式十六进制15“f”>格式十六进制25"19"
6月1日星期一:日期和时间
>现在<-getCurrentTime>稍后<-getCurrentTime>现在就开始格式化(dayOfMonth%“/”%month%“\”%year)"16/06/2014">立即设置日期格式"167">立即格式化hms"08:24:41">立即格式化tz“+0000”>立即设置日期时间格式“2014年6月16日星期一08:24:41 UTC”>格式世纪现在"20">立即格式化(“%monthName”的dayOfMonthOrd%“)“6月16日”
3年前:时间跨度
>格式(diff False)(稍后diffUTCTime)“2秒”>格式(diff True)(稍后diffUTCTime)“2秒钟内”>格式(diff True)(稍后diffUTCTime)“2秒钟前”>格式(秒0%“秒”)(稍后diffUTC时间)“2秒”
>let Just old=parseTime defaultTimeLocale“%Y”“1980”::也许是UTCTime>格式(0年)(diffUTCTime now old)"34">格式(diff True)(diffUTCTime现已过时)“35年后”>格式(diff True)(diffUTCTime现已过时)“35年前”>格式(第0天)(diffUTCTime now)"12585">格式(天0%“天”)(diffUTCTime old now)“12585天”
文件大小
>格式(最短字节)1024“1千克”>格式(字节(固定为2%“))(1024*1024*5)“5.00 MB”
科学
如果您使用的类型提供了自己的生成器,如科学
类型:
导入数据。文本。懒惰。建设者。科学scientificBuilder::Scientific->BuilderformatScientificBuilder::FPFormat->Make Int->Scientify->Builder
然后你可以使用后来
很容易:
>格式(后来的scientificBuilder)23.4"23.4"
事实上,现在已经有两个方便的组合子了(科学情报局
和scifmt公司
)对于科学
如上文所示的小数类型第节。
您可以在格式化程序中逐字记录内容:
>格式(现在为“This is printed now”。)“现在打印出来了。”
尽管有重载字符串
您可以只使用字符串文字:
>format“现在打印。”“现在打印出来了。”
您可以稍后处理使格式化程序接受参数的事情:
>format(later(const“稍后打印”)()“稍后打印。”
传递给的函数的类型后来
应返回实例属于单体
.
稍后::(a->Builder)->Format r(a->r)
格式化函数(格式
,b打印
等)将决定所选择的幺半群。对于此库顶级格式化函数希望您构建文本建设者
:
format::格式化文本a->a
因为建筑商是高效的发电机。
因此,在这种情况下,我们需要从参数中生成生成器:
格式。稍后::(a->Builder)->a->Text
要对常见类型执行此操作,只需重复使用格式化库并使用bprint:
λ> :t b打印bprint::Format Builder a->格式生成器>:t b打印int 23bprint int 23::生成器
回到后来
,我们现在可以用它来制作我们自己的打印机组合符:
>让mint=稍后(也许是“”(bprint int))>:t薄荷糖mint::积分a=>格式r(可能是a->r)
现在造币厂
是要显示的格式化程序可能是整数
:
>格式mint(读“23”)"23">格式mint(readMaybe“foo”)""
尽管更好、更通用的组合词可能是:
>让mfmt x f=稍后(可能是x(bprint f))
现在您可以使用它来格式化内容:
>格式(mfmt“Nope!”int)(readMaybe“foo”)“不!”
与其他API一起使用
为了方便起见,我们提供从生成器
typeclass和格式化
组合器。格式化
使向以下任何API添加格式变得简单需要一个建设者
严格或懒惰文本
,或a字符串
。例如,如果你有功能日志调试
,日志警告
和logInfo(日志信息)
所有类型文本->IO()
您可以执行以下操作:
>格式化日志调试(“x是:”%int)x>格式化logInfo(“y是:”%squared int)y>格式化日志警告(“zis:”%braced int)z
上面的示例适用于严格或懒惰文本
黑客攻击
使用Nix建造
请参见读ME-nix.md.
运行测试
从您的内部nix外壳
,运行电缆试验
.
测试在测试/规格
.
运行基准
起点nix外壳
这样地:nix-shell--arg doBenchmark为真
.从您的内部nix外壳
,运行阴谋家的长凳
.
要构建html基准测试报告,请运行cabal bench--benchmark-option=-obench/reports/7.2.0.html>bench/reports/7.2.0.txt
,将“7.2.0”替换为当前版本。这将输出文件工作台/报告/7.2.0.html
您可以在浏览器中打开它,也可以在终端或文本编辑器中查看bench/reports/7.2.0.txt。
基准在工作台/工作台.hs
.