今天这篇文章分析一下ghci交互解释器对类型的推导。

假设有函数fn定义如下:

let fn = map map

现在fn的类型是:

map map :: [a -> b] -> [[a] -> [b]]

推导过程:

1)首先map函数自身的类型为:

map :: (a -> b) -> [a] -> [b]

为了区分开第一个map和第二个map,将另外一个map的类型表示为:

map :: (a' -> b') -> [a'] -> [b']

在调用的过程中,有如下等式关系

(a -> b) -> [a] -> [b] = (a' -> b')

由于curry的原因,此等式等同于

(a -> b) -> ([a] -> [b]) = (a' -> b')

那么,可以得到:

a' = a -> b
b' = [a] -> [b]

将a',b'的值代入[a'] - > [b']最终得到

 [a -> b] -> [[a] -> [b]]

总结,ghci对复杂函数或表达式的类型推导就是一个简单的替换过程,不过有时候一眼看过去会很疑惑,不知道该类型所代表的意义,这是难以避免的。这是因为在haskell中大范围的使用了typeclass的概念,这个概念对应着C++中的模版,想象一下C++模版给代码带来的视觉冲击,初次使用时会很难阅读。在haskell中函数类型声明变得变本加厉,因为typeclass的存在,haskell的类型声明中大部分时候都是简单的小写字母表示,而这些字母本身并不能够带来任何类型信息的提示,大家看看这个被haskell程序员称为"boobs operator"的类型:

(.)(.) :: (a -> b -> c) -> a -> (a1 -> b) -> a1 -> c

一眼看过去大概明白这个函数是干什么的了吗?似乎很难,或许也没有必要去搞明白,不过大家可以尝试去推导一下哦:D

最新文章

  1. Android自动化测试 - Robotium之re-sign.jar重签名后安装失败提示Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES]解决方案
  2. Java使用velocity导出word
  3. MySQL MHA配置
  4. 菜鸟成长进阶之——fiddler使用总结
  5. Java基础之一组有用的类——为标记定义自己的模式(ScanString)
  6. poj3669 Meteor Shower(BFS)
  7. 版本控制:SVN中Branch/tag的使用 -摘自网络
  8. ASP.NET的六种验证控件的使用
  9. c语言基本数据类型short、int、long、char、float、double
  10. 笔记整理--玩转robots协议
  11. SEO-外部链接类型以及标准
  12. 浅析const、let与var
  13. Windows 10创意者更新ISO发布!官方下载
  14. 利用sklearn对MNIST手写数据集开始一个简单的二分类判别器项目(在这个过程中学习关于模型性能的评价指标,如accuracy,precision,recall,混淆矩阵)
  15. Log4j源码分析
  16. win7, ubuntu双系统,重装win7后,修复引导
  17. MFC停靠窗口实现(CDockablePane)
  18. Java文件编译出现 “编码 GBK 的不可映射字符”
  19. nginx js、css、图片 及 一些静态文件中出现 http://upstreamname:port 导致部分网页样式显示不正常
  20. 样条之Akima光滑插值函数

热门文章

  1. Cmdow-一个win32窗口管理命令行工具
  2. 【后台管理系统】—— Ant Design Pro组件使用(二)
  3. linux管理权限
  4. ETCD分布式锁实现选主机制(Golang实现)
  5. BZOJ[3728]PA2014 Final Zarowki
  6. PAT甲级终结——心得总结
  7. Windows + Ubuntu 16.04 双系统安装详细教程(转)
  8. Java初始化块及执行顺序
  9. 通过总线机制实现自动刷新客户端配置(Consul,Spring Cloud Config,Spring Cloud Bus)
  10. 《剑指offer》面试题21 包含min函数的栈 Java版