应用逻辑:haskell生成有理数集合

最近在上应用逻辑的课程,老师布置了一道题:

生成全部的有理数集合的无限序列,也就是所有的有理数都要包含在这个集合中,并且还要求没有重复的未化简的形式

看了两天haskell,另外借鉴了师兄去年的java代码,然后自己用haskell实现了一下,后面再附带上:代码解释+数学证明

haskell代码

mappend f []=[]					//构建工具,将指定函数f应用在指定list上
mappend f (x:xs)=f x ++mappend f xs
builds a f=set where set=a:mappend f set//构建一个无限序列的mappend工具

nextrational [a,b]=[[a,a+b],[a+b,b]]//用于生成所有的正有理数(以整数对的形式出现,a/b)
rational=builds [1,1] nextrational//正有理数的整数对序列
//结果:[[1,1],[1,2],[2,1],[1,3],[3,2],[2,3],[3,1],[1,4],[4,3],[3,5]...]
list2frac [a,b]=a/b				//将整数对转换成有理数
pq=map list2frac rational			//对整数对列表应用转换函数
p2pn []=[]
p2pn (x:xs)=[x]++[-x]++ (p2pn xs)		//将正有理数序列转换为正负有理数序列
rationals=[0]++p2pn pq				//所有有理数

代码解释

1.mappend是一个简单的映射,可以把函数应用到list上,list每个成员进行处理,和map的区别就是他是尾递归(foldl和foldr的区别也类似map和mappend的区别),下面放上这两种不同的map

//尾递归
mappend f []=[]
mappend f (x:xs)=f x ++mappend f xs
//递归
map f [] = []
map f (x:xs) = f x : map f xs

2.builds改造了下mappend,使其能够作用在一个初始值上从而产生无限序列,这个看着代码理解应该不难
3.nextrational [a,b]=[[a,a+b],[a+b,b]]这个就属于核心的函数了,我们通过把一个整数对映射出两个新的整数对的方式来发展我们的序列()
注:a代表着分子,b代表着分母,一开始的[a,b]是[1,1],不断对list中的新成员应用函数nextrational、无限发展,在后续步骤中只要对这个整数对序列一处理就可以得到a/b这个有理数
4.rational=builds [1,1] nextrational使用我们上面构建的工具和函数生成 代表着正有理数的整数对序列
的到的rational结果:[[1,1],[1,2],[2,1],[1,3],[3,2],[2,3],[3,1],[1,4],[4,3],[3,5]…]
对这个结果稍加处理就可以得到正有理数
5.使用一些函数对正整数对序列进行处理
list2frac [a,b]=a/b 函数作用:将一个整数对转换成有理数
pq=map list2frac rational 对整数对的序列应用转换函数
6.pq代表所有的正有理数,我们对其添0和添负
p2pn []=[]
p2pn (x:xs)=[x]++[-x]++ (p2pn xs) 将正有理数序列转换为正负有理数序列
rationals=[0]++(p2pn pq ) 得到所有有理数

//取前20个 take 20 rationals
[0.0,1.0,-1.0,0.5,-0.5,2.0,-2.0,
0.3333333333333333,-0.3333333333333333,1.5,-1.5,
0.6666666666666666,-0.6666666666666666,3.0,-3.0,0.25,-0.25,
1.3333333333333333,-1.3333333333333333,0.6]
//再看看前20个正整数对 take 20 rational
[[1,1],[1,2],[2,1],[1,3],[3,2],[2,3],[3,1],[1,4]
,[4,3],[3,5],[5,2],[2,5],[5,3],[3,4],[4,1],[1,5]
,[5,4],[4,7],[7,3],[3,8]]

数学证明

需要证明:
1.能够涵盖所有的有理数
2.不会出现重复
证明涵盖了所有有理数并且不会重复出现同值的有理数
OK,就这么多,因为学艺不精,有错误指出欢迎大佬纠正

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值