Chinaunix首页 | 论坛 | 博客
  • 博客访问: 346206
  • 博文数量: 105
  • 博客积分: 2730
  • 博客等级: 少校
  • 技术积分: 1110
  • 用 户 组: 普通用户
  • 注册时间: 2007-04-20 12:09
文章分类

全部博文(105)

文章存档

2013年(3)

2012年(2)

2011年(36)

2010年(34)

2009年(6)

2008年(20)

2007年(4)

分类: PHP

2011-06-27 19:17:07

声明:monad是我在水木的马甲.

发信人: monad (md), 信区: FuncProgram
标  题: Re: haskell里的printf
发信站: 水木社区 (Thu Jun 23 13:02:55 2011), 站内

这个在编译的时候是怎么被处理的呢?
(printf "xxxx" (100::Int))
(printf "xxxx")
这语句应该不是在编译的时候根据"xxxx"扫描后面应该apply了几个参数.

难道是进行自动类型推断.
那么"是否存在后面的100" 和 "是否接受后面的100" 是如何构成有效判断的呢?
我对GHC的编译不太了解, 假设一个可能的有效方法:


  扫描的时候首先不进行类型检查, 但是应该有运算符优先级的信息制导编译过程吧.
  后面有多少参数都认为是要apply的.
  因此语法分析的时候能够接受任何个数的参数.
  (推测, 对任意函数都能在这种形式上接受任意的伪apply, 比如可以(id 1 1) )
  然后按照apply的语句进行类型推断:
    printf "xxxx"到底是 (r) 还是 (a -> r) 就要靠自动推断, 因为发现后面还有apply进来的参数, 所以得到 (r)是不可行的, 而 (a -> r)是可行的. 所以类型推断在(printf "xxxx")部分标记为 (a -> r).
    然后推断printf "xxxx" (100::Int) 到底是什么类型, 发现后面没有参数, 正好匹配(r)的类型, 所以就完成了类型推断.


(就本推测)对于printf来说, 依然是静态类型的. 因为类型推断在编译的时候已经完成了, 而执行的时候到底参数够不够就不是编译的问题了.

printf :: (PrintfType r) => String -> r
printf fmts = spr fmts []

instance (PrintfArg a, PrintfType r) => PrintfType (a -> r) where
    spr fmts args = \ a -> spr fmts (toUPrintf a : args)

经过了类型推断, 认为(printf "xxxx")是 (a -> r)以后, 就可以进行evaluation了:
  (printf "xxxx") --被重写成:
  spr "xxxx" []  ---它的类型是(a -> r):
  \ a -> spr "xxxx" (toUPrintf a : [])
  把100 给塞进去 ...应该是dui(三声)进去:
  spr "xxxx" (100 : [])
  spr "xxxx" [100]

因此, 实际上的printf就是在对一个list进行参数处理了.
※ 修改:·monad 于 Jun 23 13:21:04 2011 修改本文·[FROM: 58.195.14.*]
※ 来源:·水木社区 ·[FROM: 58.195.14.*]
阅读(812) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~