跳至主要內容

Haskell笔记1

Mr.Lexon大约 3 分钟functional-program

Haskell笔记1

函数1

haskell的函数参数可以分解成这样

subSolution :: Integer -> [(String,Integer)] -> String -> String
subSolution n [] a = a
subSolution n ((k,v):xs) a
  | n == 0 = a
  | n >= v = subSolution res ((k,v):xs) (a++k)
  | otherwise = subSolution n xs a
  where res = n - v

以这个函数为例子:第二个入参是一个list+tuple的组合,所以在入参这里就可以直接分解成:

((k,v):xs)

首先k指的是tuple的第一项,则v是第二项,而xs指的是list剩余的元素,这对于我写了不少oop程序来说非常惊奇,并且从其向外延申时,他这里就出现了循环的作用,因为每一次递归都是获取list本身的元素,然后通过尾递归变成了循环。

函数2

还是以函数1的例子进一步解释,首先第一行展示的是这个东西:

subSolution :: Integer -> [(String,Integer)] -> String -> String

用原本的函数理解,他是定义了形参类型,并且除最后一个之外其他都是输入参数。不过我还有另一种理解,就是这个函数还同时描述了函数的变换过程,从流程出发,首先subSolution接受第一个参数,并返回接受第一个参数的函数。然后第二、第三,当接受完第三个函数时,函数执行调用并使最后的结果返回String,在这个基础上它形式上柯里化了。

Map.lookup

这个函数取自于:

import qualified Data.Map as Map

它允许你通过键在映射(也称为关联数组或字典)中查找值。例子:

let myMap = Map.fromList [(1, "one"), (2, "two"), (3, "three")]
let value1 = Map.lookup 2 myMap
let value2 = Map.lookup 4 myMap

注意,它返回的值是一个Maybe a所以返回原本值则需要使用Just(适用于一切Maybe)

Map.fromList

Map.fromList是一个高效的Map创建之后会返回一个二叉搜索树。例如:

import qualified Data.Map as Map

如果它用于删除和搜索比原本的[(String,Int)]要高效一些。

提示

突然想到,hs函数的所有类型包括类也要形参也好,都是一个归纳类型,那就意味着在设计的时候需要考虑全面并且对他做一些归纳证明,那也难怪为啥形式化证明完成之后会变得无比的可靠。

函数3

有一个有趣的例子:

reservedRoMen :: String -> Integer -> Integer
reservedRoMen "" n = n
reservedRoMen (x:y:xs) n
  | isJust two = reservedRoMen xs (n + fromJust two)
  | isNothing two && isJust one= reservedRoMen (y:xs) (n+ fromJust one)
  | otherwise = -1
  where one = Map.lookup [x] examlpNap
        two = Map.lookup (x:[y]) examlpNap
reservedRoMen [x] n
  | isJust lastOne = n + fromJust lastOne
  | otherwise = -1
  where lastOne = Map.lookup [x] examlpNap

看到two变量的定义:

two = Map.lookup (x:[y]) examlpNap

还有函数形参的定义:

reservedRoMen (x:y:xs) n

结合两者我们看到一点就是xy可以这么组合:

(x:[y])

这个描述了一个事情就是:将x[y]组合成一个新的list,这一点上就很有趣,形参可以通过任意形式结构,并且可以通过解构的方式再重新结构,这一点上我认为十分的灵活。 然后,在此处:

where lastOne = Map.lookup [x] examlpNap

这里为啥是[x]而不是x呢,因为在形参定义之后:(x:y:xs),x就变成了Char而加上这个[]才能将其转换成String

map

这个函数是作用到一个list上面,然后第一个参数是一个函数。用于对list中的每个元素做输入函数的调用。用法同oop语言的map

foldl

这个函数特有意思,他的作用是从左边开始,依次折叠函数,如何折叠通过函数定义,就是将list元素通过折叠操作累进到唯一一个结果。它可以轻松做到一些原本oop需要复杂实现的函数比如一个数的阶乘或者是对一个list里面的数求和。

上次编辑于:
贡献者: Lexon