声明: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) |