美文网首页
Haskell笔记2

Haskell笔记2

作者: b7c9833ccf70 | 来源:发表于2018-06-12 16:41 被阅读0次

1 Polymorphic Types

在很多情况下,不同的数据类型会有相同功能的函数,例如判定相等或者不等,List的append等等。如果我们对每一个都单独定义的话,会产生非常多的功能一致但只有类型不同的函数。在这种情况下,polymorphic type就显得十分有用。

例如 reverse 函数, 他将一个list颠倒过来。 我们希望它对各种类型都适用那么就可定义:

reverse::[a] ->[a]

注意此处 a 即任意一种类型,[a]是显式的指明它为一个List型的类型。但是a也可以为List,[a]可以为以一种类型的list的list。

再比如说zip,

zip::[a]->[b]->[(a,b)]

此处a,b可以为一种类型,也可以为不同类型。

2 Higher-order functions

先简单介绍一下普通的function。

最基本的函数其类型是:

T->R

T,R指任意类型,T为函数的参数,R为函数的输出值。

在函数定义时,例如higher-order function, 我们可以不必再原始定义中给出参数,而是在第一次需要参数时给出定义。例如我们有函数

f::(a->a)->(a->b)->a->b

f func1 func2 = func3

                          where func3 input = if func1 input then func2 input

                                                              else input

在函数定义的最初,我们并没有定义 input(函数参数),但是这并不影响函数定义的合法性。 我们在func3中调用了它。这么做可以提高程序可读性。

另外,如果在函数中应用了lambda expression, 我们也可以在函数中省略参数,这只是一个参数声明的平移,因为我们还会在第一次用到参数时定义它。例如:

f::Int->Int

f = (\x->x+x)

虽然我们没有以正常的f x =..来定义函数,但是在anonymous function中我们还是给出了定义。

Haskell中,所有的函数都接收一个参数,返回一个值。那么如何解释之前写过的接收多个参数的函数?

----它们被称之为Curried functions(哎,我也不知道为什么Haskell有这么多和食物有关的术语,可能大佬是个吃货吧)。

举一个简单的例子---

引用Learn You a Haskell for Great Good! 

http://learnyouahaskell.com/higher-order-functions

max:: Int->Int->Int

我们不管这个函数如何实现,总之它会选出两个数之中较大的一个。

这个函数接收第一个参数后,会返回一个接收Int的函数,最终返回a。

另一种写法为 a->(a->a), 看,它返回的是一个函数!

如果我们定义一个函数是 f = max 3,我们再调用f的时候,实际上是把缺少的一个参数补给了max。

这种应用函数的方法为 --- partial application。

回到Higher order functions来,对应只接受一个参数的函数它是first order,剩余的即higher order。higher order中会以函数作为参数,在函数定义中以括号标识出来,例如:

f:: (a->a)->b->(a,b)

(a->a)即以个以a为参数返回a的函数。

3 Lambda-abstractions

Lambda abstractions实际上是为了创造anonymous function,可以在定义函数之间方便的构造一个新的辅助函数。它的大概形式如下:

(\x -> x + x) x; (\x y -> x+y) x y

括号中为函数的定义,括号外紧跟的为函数的输入,它会替代所有x(在\x->中),或者二元的话就将对应替代---第一个数对应第一个参数,第二个对应第二个参数。

稍微复杂点的形式可以是嵌套的

大致为: \x-> (\y..) 这实际上为f.y

一个复杂一点的例子:

map (\x -> (map (\y->(x,y)) [1..10])) [0..9]

map函数对[0..9]的每一个元素都调用了中间的函数,而中间的关于x的函数是关于另一个map的函数,这个map中又有关于y的函数。它实际上等效于list:

[(x,y)|x<-[0..9],y<-[1..10]]

值得注意的一点是,transition的关系只有在括号的嵌套之中才有,如果是括号之外的另外一个anonymous function,那么就无任何关系,例如:

((\x-> x+1) 2) + ((\x->x+2) 3)

它的输出为8.

4 Higher order function 与  list

所有的list,都可以由concat,filter,map函数构造出来。

例如:

original = [ (x,y) | x <- [1..100], y <- [1..x], x `mod` y > 0 ]

它可以被改写为:

alternative = concat (map(\x->(map (\y->(x,y)) (filter (\y-> x`mod`y>0) [1..x]))) [1..100])

需要提醒的一点是,在\x->之后的括号中都为关于x的函数,所以x可以被用于任何一个子函数中,但是filter,map为分开的两个函数,所以关于y的两个函数并无关联。

5 List Function

以list为参数的function需要注意函数的non-exhaustive即详尽性或者全面性。

使用x:xs迭代性可避免各种各样的pattern match缺失。

6 ':' operator 与 '++' operator

':' operator 与 '++' 都是返回list的operator,但是:

':'  它接受一个任意类型参数加一个此类型的list参数,具体来讲是把一个参数放到一个list的首位。即类似: 1:[2,3,4] = [1,2,3,4] 或者 [1,2]:[[3,4],[5,6]] = [[1,2],[3,4],[5,6]]

a->[a]->[a]

'++': 它接受两个list类型参数,并把第二个连入第一个的尾部。即类似:

[1,2] ++ [3,4] = [1,2,3,4]

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

相关文章

  • Haskell笔记2

    1 Polymorphic Types 在很多情况下,不同的数据类型会有相同功能的函数,例如判定相等或者不等,Li...

  • haskell笔记(2) - funtions

    pattern matching 如果模式匹配多个值,必须用括号括起来(if you want to bind t...

  • Haskell笔记4

    divide and conquer 这一部分主要是对作业中divideAndConquer的解释,因为我觉得这个...

  • Haskell笔记3

    1.foldr foldr::(a->b->b)->b->[a]->b foldr函数应用在list上,它的功能就...

  • Haskell笔记1

    前言 这个学期开始学习Haskelll(主要关于Codeworld和ghci),感觉很多东西和OOP不一样,最近感...

  • 函数式的宗教-00: 认识lisp(clojure)与haske

    总体大纲: lisp与haskell简单介绍 lisp与haskell应用领域 lisp与haskell技术分析 ...

  • monad以及monad的四条定理

    haskell的范畴是hask范畴(haskell的所有类型隶属于hask范畴),所以haskell的所有函子都是...

  • 01 数据类型

    swift中结构体在haskell中的描述 枚举类型在haskell中的描述 枚举携带类型在haskell中描述 ...

  • Haskell基础

    [TOC] 假设读者都有函数式编程方面的知识。这个笔记只是记录笔者觉得Haskell 最有特点的几个地方。 概念 ...

  • Haskell学习笔记(一)

    这一系列的笔记主要参考中文版的 Real World Haskell,这篇博文作为本系列的第一篇,先介绍一下Has...

网友评论

      本文标题:Haskell笔记2

      本文链接:https://www.haomeiwen.com/subject/etzleftx.html