hasell 基础题解(09)

一年中的第几天

【题目】给定年月日,求这一天是该年份中的第几天。元旦作为该年的第一天。

这个问题相对容易。
关键是算出 2 月份有多少天。
把每个月的天数放在数组中,然后累加已过去的月份的天数,再加上不足一个月的天数。

haskell 代码如下:

di_ji :: (Int,Int,Int) -> Int
di_ji (y,m,d) = 
  let run_nian = y `mod` 4 == 0 && y `mod` 100 /= 0 || y `mod` 400 == 0
      mon = [31,if run_nian then 29 else 28
            ,31,30,31,30,31,31,30,31,30,31]
  in sum (take (m-1) mon) + d

main = do
  s <- getLine
  let [y,m,d] = words s
  print $ di_ji (read y, read m, read d)

这里可以看到 haskell 作为纯函数式的语言,一切都是表达式。表达式必须返回一个值。
if … then …else … 就是一个表达式,无论如何,它都会吐出一个同样类型的值。
let … in … 也是一个表达式,它的值就是 in 表达式的返回值。
read 是一个多态的函数。它可能返回各种类型的值。在这里,编译器看到了 di_ji 的参数是 Int
所以它选择了返回 Int 的那个read 实现版本。
实际上 do 语句块也是一个表达式。它是 Monad IO 函数的串联式的一种语法糖。
看起来好像是一条条的命令语句,实则只是一个表达式。

总之,haskell 中只有函数,表达式,没有命令,
无法赋值,没有循环,break, goto 等所谓控制程序流程的东西都没有!!
你无权知道表达式求值的先后顺序。
你只是定义表达式间的信赖关系。
你只能问某个表达式的结果是多少?至于如何设计计算路径,全是编译器的事。
哪个表达式什么时候求值,甚至是到底要不要求值,都是编译器的责任。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值