haskell学习笔记(8)-haskell的类型系统
2017-12-28 09:51
459 查看
类型推导
haskell因为支持类型推导,所以大多数时候不用显式写出类型声明,但是如果要写库的话,最好是写上类型声明,可以当做文档使用,看上去一目了然。haskell的类型推导比大部分语言要强不少,例如和同样有类型推导的kotlin相比,kotlin并不支持传入参数的自动推导
例如
//a b参数都要写明类型 fun max(a:Int,b:Int)=if (a>b) a else b //这样是编译不过的 fun max(a,b)=if (a>b) a else b //kotlin类型推导基本上只能用作声明变量 var a=10;
可以看出,kotlin的类型推导基本上只是一个简单的根据值推断出类型的过程
我们看看haskell的
--这样完全可以 max' a b=if a>b then a else b
所以haskell的类型推导还包括了上下文的类型推导,实际上我们在ghci里查看他的类型,会发现结果是,我们先将Ord看成一个接口,所以haskell可以通过上下文自动推导出需要传入的值需要实现Ord接口(一个可以比较的接口)
这种上下文的类型推导,一般在命令式语言里很难实现,而在函数式语言里相对容易,因为函数式语言每个语句都有值,可以使用动态分析来得到返回值,而且函数式语言没有复杂的控制结构,方便分析。
max' :: (Ord a)=>a->a->a
当然,虽然haskell的类型推导很强大,不过在函数比较复杂的情况下,如果不写明类型,很容易让函数使用者无所适从,因为单看语句很难明白要传入什么,会返回什么。
类型系统
我们往常在静态语言里写代码的时候,都是将类型声明和函数本身混合在一起,例如下面这个函数,即包括了访问控制符public,又包括了函数名max,参数名a,bpublic int max(int a,int b) { return a>b?a:b; }
在接触haskell之前,我觉得这样挺自然的,不过接触haskell的类型和函数实现分开写之后,感觉这样反而会使代码更清晰。
--类型声明 max' :: (Ord a)=>a->a->a --实现 max' a b=if a>b then a else b
我们不断在新语言里加一些新结构,语法糖,很大原因就是希望代码看起来更具结构性,更简洁,例如for来替换while,switch来替换if else,那其实我个人觉得,将类型声明和代码主体分开写,也是一种使代码更简洁的方法。不知道大家怎么看。
haskell因为有不全调用以及高阶函数的存在,所以他的类型声明第一次看的时候都会略显怪异,每个参数都是用->来间隔,不过习惯了高阶函数就好。
addThree :: Int -> Int -> Int -> Int addThree x y z = x + y + z --其实就等价于 addThree :: Int ->( Int -> (Int -> Int)) addThree x y z = x + y + z
如果写的不是实际的类型而是类型变量,其实就和其他语言里的泛型差不多
--haskell ghci> :t head head :: [a] -> a --等价的java声明 public<T> T head(T[] array){}
再看下面这个,其实也和java泛型加类型参数的上限差不多
ghci> :t (==) (==) :: (Eq a) => a -> a -> Bool --等价的java声明 一直想吐槽设定java类型参数的接口限制用的是extends关键字而不是implement public<T extends Eq> T head(T[] array){}
虽然我看的几本书上都说haskell的类型声明typeclass比其他语言的泛型强很多。。其实我还是觉得差不多滴,目前看来,haskell比其他语言强很多的特性基本上就是,列表推导,高阶函数 ,其他的特性基本上都是这两个引申出来的。
欢迎关注我的github
https://github.com/luckyCatMiao
相关文章推荐
- Haskell 学习笔记 1 --环境搭建与类型系统(Haskell Tutorial 1--Getting start with Haskell)
- Haskell 笔记(三)类型系统
- 【Linux学习笔记】Linux/UNIX系统标准数据类型
- C#学习笔记 系统数据类型
- .NET学习笔记(三) ------系统类型和通用操作 (下)
- C++学习笔记-2 C++类型系统
- Haskell 笔记(三)类型系统
- javascript类型系统 Window对象学习笔记
- JS学习笔记(4)类型系统
- Linux学习笔记(系统目录结构,ls,文件类型,alias)
- C#及.NET学习笔记之从C#2.0角度看.NET2.0类型系统
- Asp.Net Ajax 学习笔记11 Microsoft AJAX Library中的面向对象类型系统
- Unity3D之Mecanim动画系统学习笔记(八):Animator Layers(动画分层)
- 27 尽量少做类型转换——effective c++学习笔记
- JavaScript学习笔记4-变量类型
- lua学习笔记---值,类型
- Linux基础学习笔记之如何使vm下centos启动后就自动以root身份登录系统
- iOS学习笔记:instancetype关联返回类型
- C++ 学习笔记(7)类、友元、默认构造函数(default)、可变数据成员(mutable)、前向声明和不完全类型、聚合类、字面值常量类
- swift学习笔记之函数形参,返回值以及函数类型