most important thing is to just build vague shape of FP
why haskell ?
1 i want to be a big data programer。because it is a new career。And i want to be more outstanding in a new professional occupation. Maybe it will earn more money 。
2 spark is popular with real-time business intelligence。
3 spark is coded with scala.
4 scala is a multi-program-padadigm language combines object-oriented and functional programming。
5 haskell is a functional programming language which has more refrence book。
i want study haskell until i know some common features about programming language 。i needn't to build project.
start out
1 build environment
1 i apply a aliyun ecs server with OS Ubuntu。
2 i install the docker
3 pull image with ghc with run the commond docker search ghc
and docker pull mitchty/alpine-ghc
4 run the docker container with command service docker start
5 run ghci
root@ubuntu:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest fce289e99eb9 2 months ago 1.84kB
mitchty/alpine-ghc latest 4f004e840ddb 2 years ago 1.76GB
root@ubuntu:~# docker run -t -i 4f004e840ddb
bash-4.3#
bash-4.3#
bash-4.3# ghci
GHCi, version 8.0.2: http://www.haskell.org/ghc/ :? for help
Prelude>
simple arithmetic.(简单算术)
1 we can use parentheses(圆括号) to make the precedence(优先级) explicit(明确的)
5*-3
the compiler will regard *-
as a function.
2 &&
means a boolean and
, ||
means a boolean or
. not
negates a True
or a False
.
Prelude> 5*-3
<interactive>:2:2: error:
• Variable not in scope: (*-) :: Integer -> Integer -> t
• Perhaps you meant one of these:
‘*’ (imported from Prelude), ‘-’ (imported from Prelude),
‘*>’ (imported from Prelude)
Prelude> 5*(-3)
-15
Prelude> 5 `*` 3
<interactive>:4:4: error: parse error on input ‘*’
Prelude> 5 `/` 3
<interactive>:5:4: error: parse error on input ‘/’
Prelude> 5 `div` 3
1
Prelude> true && true
<interactive>:7:1: error:
• Variable not in scope: true :: Bool
• Perhaps you meant data constructor ‘True’ (imported from Prelude)
<interactive>:7:9: error:
• Variable not in scope: true :: Bool
• Perhaps you meant data constructor ‘True’ (imported from Prelude)
Prelude> True &&True
True
3 equals
Prelude> 2==2
True
Prelude> 3!=2
<interactive>:10:2: error:
• Variable not in scope: (!=) :: Integer -> Integer -> t
• Perhaps you meant one of these:
‘>=’ (imported from Prelude), ‘==’ (imported from Prelude),
‘/=’ (imported from Prelude)
Prelude> 3/=3
False
4 +
works only on things that are considered numbers, ==
works on any two things that can be compared.
5 there are two kinds of function called infix function
中缀函数,like this one . 5/5=1
Prelude> 5 `div` 5
1
and prefix function
前缀函数
succ 8
9
6 we separate function
and parameters
with space .like this one
min 3 5
3
7 Function application (calling a function by putting a space after it and then typing out the parameters) has the highest precedence
succ 9 + max 5 4 + 1
16
8 a function takes two parameters, we can also call it as an infix function by surrounding it with backticks.
div 92 10
9
92 `div` 10
9
first hs function that you defined
Prelude> doubleMe x = x+x
Prelude> doubleMe 4
8
Prelude>
it looks like when it calls . functionName
space input parameter
= functionBody
.likes lamda
expression.
bash-4.3# touch 01.hs
bash-4.3# vi 01.hs
bash-4.3# pwd
/haskell
bash-4.3# ghci
GHCi, version 8.0.2: http://www.haskell.org/ghc/ :? for help
Prelude> :l 01.hs
[1 of 1] Compiling Main ( 01.hs, interpreted )
Ok, modules loaded: Main.
*Main> doubleMe 9
18
in haskell function and expression must return a result
1 we input this command to login to docker container
docker exec -it 0bb73fa62fe0 /bin/bash
2 and modify 01.hs
doubleSmallNumber' x = (if x > 100 then x else x*2) + 1
3 execute it
*Main> :l 01.hs
[1 of 1] Compiling Main ( 01.hs, interpreted )
Ok, modules loaded: Main.
*Main> doubleSmallNumberAndPlus1 45
91
1 if statement in Haskell is that it is an expression.
2 in haskell function and expression must return a result
3 the else is mandatory(强制性的)。else 必须存在
4 use '(apostrophe ) to either denote a strict version of a function (one that isn't lazy) 是个严格的 function,不是lazy的
5 the function name we didn't capitalize in haskell 函数的首字母不能大写
6 When a function doesn't take any parameters, we usually say it's a definition (or a name). Because we can't change what names (and functions) mean once we've defined them 像java中的常量字符串
List
1 lists are a homogenous(单一材料的 ) data structure
2 use the let
keyword to define a variable
3 lists are denoted by square brackets and the values in the lists are separated by
commas
4 "hello" is just syntactic sugar(语法糖) for ['h','e','l','l','o'].
5 merge two lists use ++
operator
6 Haskell has to walk through the whole list on the left side of ++
7 putting something at the beginning of a list using the :
operator
Note: [], [[]] and[[],[],[]] are all different things. The first one is an empty list, the seconds one is a list that contains one empty list, the third one is a list that contains three empty lists.
8 get element by index .use !!
9 using <, <=, > and >= to compare lists
ghci> [3,2,1] > [2,1,0]
True
ghci> [3,2,1] > [2,10,100]
True
ghci> [3,4,2] > [3,4]
True
ghci> [3,4,2] > [2,4]
True
ghci> [3,4,2] == [3,4,2]
True
没啥吊用 ,就比较数组第一个元素的大小
List 的api
head
original list is not change .and returns the head
ghci> head [5,4,3,2,1]
5
tail
the original list is not change .and returns sublist which removes the head
ghci> tail [5,4,3,2,1]
[4,3,2,1]
last
和head
对应 。
ghci> last [5,4,3,2,1]
1
init
和tail
对应 the original list is not change .and returns sublist which removes the tail
ghci> init [5,4,3,2,1]
[5,4,3,2]
粗看上面的api,感觉和java的大部相同,感觉什么api,有病吧~~~
但是配上这幅图,瞬间秒懂~~~~
length
null
checks if a list is empty. reverse
经过这些函数,原来的数组还是不变的。
ghci> take 3 [5,4,3,2,1]
[5,4,3]
ghci> take 1 [3,9,3]
[3]
ghci> take 5 [1,2]
[1,2]
ghci> take 0 [6,6,6]
[]
if we try to take more elements than there are in the list, it just returns the list. If we try to take 0 elements, we get an empty list.
ghci> drop 3 [8,4,2,1,5,6]
[1,5,6]
ghci> drop 0 [1,2,3,4]
[1,2,3,4]
ghci> drop 100 [1,2,3,4]
[]
maximum
maximum
sum
product
ghci> sum [5,2,1,6,3,2,5,7]
31
ghci> product [6,2,1,2]
24
ghci> 4 `elem` [3,4,5,6]
True
ghci> 10 `elem` [3,4,5,6]
False
Texas ranges 德州区间
ghci> [1..20]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
ghci> ['a'..'z']
"abcdefghijklmnopqrstuvwxyz"
ghci> ['K'..'Z']
"KLMNOPQRSTUVWXYZ"
specify a step 指定步长
ghci> [2,4..20]
[2,4,6,8,10,12,14,16,18,20]
ghci> [3,6..20]
[3,6,9,12,15,18]
To make a list with all the numbers from 20 to 1, you can't just do [20..1], you have to do [20,19..1].
不过不能用于float
ghci> [0.1, 0.3 .. 1]
[0.1,0.3,0.5,0.7,0.8999999999999999,1.0999999999999999]
Prelude> take 24 [13,26..] //f(x) = take(n,set)
[13,26,39,52,65,78,91,104,117,130,143,156,169,182,195,208,221,234,247,260,273,286,299,312]
ghci> take 10 (cycle [1,2,3]) // f(x) =cycle(set)
// f(y) = take(10,f(x)) f(x) means what x returns
[1,2,3,1,2,3,1,2,3,1]
ghci> take 12 (cycle "LOL ")
"LOL LOL LOL "
ghci> take 10 (repeat 5)
[5,5,5,5,5,5,5,5,5,5]
Prelude> replicate 3 10
[10,10,10]
haskell和数学
set notationThe part before the pipe is called the
output function
, x
is the variable
, N is the input set
and x <= 10 is the predicate
竖号, they called
pipe
pipe's left is output function control output format ,pipe's right is predicates that seperates with commas,and controls x axis area .控制x轴的区间,有哪些元素
ghci> [x*2 | x <- [1..10]]
[2,4,6,8,10,12,14,16,18,20]
ghci> [x*2 | x <- [1..10], x*2 >= 12]
[12,14,16,18,20]
ghci> [ x | x <- [50..100], x `mod` 7 == 3]
[52,59,66,73,80,87,94]
就像是初中数学的二元一次方程。 给定了x的条件,求y的解集。y=2x
<-
这个符号可以翻译成belong to 。
before the pipe gives the expression or function that returns a result set,after the pipe gives the predicate of X element
1 题目: 把输入的集合,小于10的奇数,用“BOOM!”代替。大于10的奇数,用"BANG!" 代替。
first ,the predicate is x<-inoutParam ,and odd x
需要all the predicates evaluate to True
second the before pipe part ,change value that is true to what this function want to return .把符合条件的y值,经过y=f(x) 转化成想要返回的集合。if x<10 then 'BOOM!' else 'BANG!'
boomBangs xs = [ if x < 10 then "BOOM!" else "BANG!" | x <- xs, odd x]
更变态的是还支持多元方程。如下:
ghci> [ x*y | x <- [2,5,10], y <- [8,10,11]]
[16,20,22,40,50,55,80,100,110]
f(z) =xy . x belong to [2,5,10] .....
这个假如说是数据库返回的值的话,不就是笛卡尔积嘛
How about a list comprehension that combines a list of adjectives and a list of nouns … for epic hilarity.
如果是一个形容词和一名词,组成一个短语。
ghci> let nouns = ["hobo","frog","pope"]
ghci> let adjectives = ["lazy","grouchy","scheming"]
ghci> [adjective ++ " " ++ noun | adjective <- adjectives, noun <- nouns]
["lazy hobo","lazy frog","lazy pope","grouchy hobo","grouchy frog",
"grouchy pope","scheming hobo","scheming frog","scheming pope"]
output function can also be a constant.
length' xs = sum [1 | _ <- xs]
_
this symbol refers to anything that you will never use 。we discover the output function is a constant .the predicate has no variable to use ,so the _
symbol borns。
nested list comprehension also is possible.
ghci> let xxs = [[1,3,5,2,3,1,2,4,5],[1,2,3,4,5,6,7,8,9],[1,2,4,2,1,6,3,1,3,2,3,6]]
ghci> [ [ x | x <- xs, even x ] | xs <- xxs]
[[2,2,4],[2,4,6,8],[2,4,2,6,2,6]]
first ,we treat xxs as a list contains 3 elements.And we read list comprehension from outside .we regard the inner list comprehension as the output function x。 like this [X|xs<-xss]
。and then we read the inner list comprehension.xs as the input parameter.the inner output function is x . x belongs to xs.another predicate is even x.
tuple
just like this . image.pngi think tuple is mostly like object in java .like class with no operation. just basic data type combnation or assemble . mixed some data type into an element .then tuple gave birth to .
difference between list and tuple
1 list's elements are homogenous. are the same data type . But tuples has no limitation.
2 list can be infinite .but tuple must know exactly how many values you want to combine.
3 list elements surround with squre brackets[] , but tuples elements surround with parentheses. and in an element. seperate with commas
tuple API
fst takes a pair and returns its first component.
ghci> fst (8,11)
8
ghci> fst ("Wow", False)
"Wow"
zip. It takes two lists and then zips them together into one list by joining the matching elements into pairs.
ghci> zip [1,2,3,4,5] [5,5,5,5,5]
[(1,5),(2,5),(3,5),(4,5),(5,5)]
ghci> zip [1 .. 5] ["one", "two", "three", "four", "five"]
[(1,"one"),(2,"two"),(3,"three"),(4,"four"),(5,"five")]
ghci> zip [5,3,2,6,2,7,2,5,4,6,6] ["im","a","turtle"]
[(5,"im"),(3,"a"),(2,"turtle")]
Prelude> let trianglesf' = [(a,b,c)|c<-[1..10],b<-[1..10],a<-[1..10],a^2+b^2==c^2]
Prelude> trianglesf'
[(4,3,5),(3,4,5),(8,6,10),(6,8,10)]
记得要加'
remember to add '
.
网友评论