ghci对haskell的类型推导
今天这篇文章分析一下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
ghci对haskell的类型推导的更多相关文章
- Java 8 新特性之泛型的类型推导
1. 泛型究竟是什么? 在讨论类型推导(type inference)之前,必须回顾一下什么是泛型(Generic).泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据 ...
- C++11 - 类型推导auto关键字
在C++11中,auto关键字被作为类型自动类型推导关键字 (1)基本用法 C++98:类型 变量名 = 初值; int i = 10; C++11:auto 变量名 = 初值; auto i ...
- 图说函数模板右值引用参数(T&&)类型推导规则(C++11)
见下图: 规律总结: 只要我们传递一个基本类型是A④的左值,那么,传递后,T的类型就是A&,形参在函数体中的类型就是A&. 只要我们传递一个基本类型是A的右值,那么,传递后,T的类型就 ...
- C++11 图说VS2013下的引用叠加规则和模板参数类型推导规则
背景: 最近在学习C++STL,出于偶然,在C++Reference上看到了vector下的emplace_back函数,不想由此引发了一系列的“探索”,于是就有了现在这篇博文. 前言: ...
- c++相关的类型推导
c++11和boost库增加许多关于类型推导(编译期)的关键字和类型, 用好这些机制, 对于编写项目的一些组件帮助颇大.正所谓工欲善其事,必先利其器. 1.初始化某种类型的变量 auto var = ...
- Effective Modern C++翻译(3)-条款2:明白auto类型推导
条款2 明白auto类型推导 如果你已经读完了条款1中有关模板类型推导的内容,那么你几乎已经知道了所有关于auto类型推导的事情,因为除了一个古怪的例外,auto的类型推导规则和模板的类型推导规则是一 ...
- Swift学习(三)类型推导&基本运算&分支&循环
一.Swift中类型推导&基本运算 Swift中类型推导 如果一个标识符在定义时有直接赋值,那么可以根据后面赋值的类型,来推导出前面标识符的类型,这样前面标识符的(:类型)可以省略 查看标识符 ...
- C++11类型推导
[C++11类型推导] auto 关键字.这会依据该初始化子(initializer)的具体类型产生参数: 除此之外,decltype 能够被用来在编译期决定一个表示式的类型. 参考:http://z ...
- 类型推导:函数模板与auto
1.从函数模板谈起 函数模板的类型推导机制是在c++98时代就有的,auto的类型推导机制与其基本一致,所以先理解函数模板类型推导. 函数模板可以用如下代码框架表示: #template<typ ...
随机推荐
- [BZOJ3527][ZJOI2014]力:FFT
分析 整理得下式: \[E_i=\sum_{j<i}{\frac{q_i}{(i-j)^2}}-\sum_{j>i}{\frac{q_i}{(i-j)^2}}\] 假设\(n=5\),考虑 ...
- Mybatis, 实现一对多
我这里是拿商品做为例子 不多说直接上代码 Mapper.xml <?xml version="1.0" encoding="UTF-8"?> < ...
- 字节对齐#pragma pack
这是给编译器用的参数设置,有关结构体字节对齐方式设置, #pragma pack是指定数据在内存中的对齐方式. #pragma pack (n) 作用:C编译器将按照n个字节对 ...
- react-native 组件之间传值
1.通过 AsyncStorage 将值保存在本地(最低端的方法) import { AsyncStorage, } from 'react-native'; // 保存 IP AsyncStorag ...
- python值的引用传递和go语言的值传递
一:值传递 实参a 原本指向地址 1638212,代表1638212这个地址的值是3.在swap函数中,实参a将值拷贝给形参a,形参a此时也在内存中拥有地址,地址= xxxx,值为3,在所有的函数体内 ...
- SpringBoot系列:二、SpringBoot的配置文件
SpringBoot的配置文件在resources文件夹下 springboot的配置文件支持两种形式的写法,一种是经典的properties另一种是yml yml通过空格缩进的形式来表示对象的层级关 ...
- 阶段1 语言基础+高级_1-3-Java语言高级_1-常用API_1_第8节 Math类_19_Math练习:小学数学真题
题目 画数轴 解题思路 强转成int类型就会舍弃小数位数 输出最终的数量 如果用Math.ceil的方式的话
- C++笔记(2)——一些语法基础知识以及基本算法知识
今天和PAT无直接相关的关系,主要是关于一些语法/算法的笔记,因为我发现自己的基础还没有打扎实,有些时候看别人的代码还会觉得一头雾水,不明白代码的含义. 一些C/C++语法 先从语法开始吧.这部分很琐 ...
- powerdisigner
- Postman—上个接口返回数据作为下个接口入参
//将数据解析成json格式 var data=JSON.parse(responseBody); //获取totalRentPrice值 var totalRentPrice=jsonData.da ...