Haskell笔记1
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
结合两者我们看到一点就是x和y可以这么组合:
(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里面的数求和。