初識Haskell 三:函數function


Discrete Mathematics Using a Computer的第一章Introduction to Haskell進行總結。環境Windows


函數毫無疑問是函數式語言的核心。

在Haskell中(無特殊指明,以下皆是指在Haskell下),一個表達式用函數完成計算被稱為a function application,函數后加空格然后跟隨參數(arguments),如有多個參數,也以空格作為分隔。

函數的返回值即函數的類型,如一個函數的參數是類型a,返回值是類型b,寫作a → b(在Haskell中用 -> 表示),讀作a arrow b。

操作符其實也是函數,它有2個參數,寫在2個參數中間,其實也可以像正常函數一樣寫在前面,但需要加( )如:

同樣的,也可以像對待操作符一樣將函數放在2個參數中間,但要加反引號( single-back-quote, ` ),如:

將函數定義在Haskell腳本文件(.hs)中,載入(在ghci中 :load)后,即可使用。

函數的聲明:

  function_name :: argType1 -> argType2 ->  ... ->argTypen ->resultType

函數體:

 function_name arg1 arg2 ... argn = expression that can use the arguments

  

模式匹配pattern matching

在定義函數時,為應對不同情況,可以有多個函數體,如:f :: Integer -> String

f 1 = "one" f 2 = "two" f 3 = "three"

is_three :: Int->Bool
is_three 3 = False
is_three x = True --這里的x代表任何Int值,但由於是第二條執行到這一條就代表了x不是3

  在得到參數執行時,會從第一條開始比較是否符合,當遇到符合的才會執行,執行后即該函數執行完成,如果沒有符合的會報錯,如:

元組和list都可以作為函數參數,其中list有兩種形式:

1. [1,2,3, x ]   -- 表示list中有具體個數

2. x:xs      -- 表示至少有1個元素的list

3. xs      -- 通用的list,包括空list

當用x:xs的時候,可以使用@來給整個列表命名,如lst@(x:xs),則在之后的代碼中可用lst來指代(x:xs)。

練習題:

  我的答案:

exercise3 :: Char -> Bool
exercise3 'a' = True
exercise3 x = False

exercise4 :: String -> Bool
exercise4 "hello" = True
exercise4 x = False

exercise5 :: String -> String
exercise5 (' ':xs) = xs
exercise5 xs = xs

 另一種應對多種值的方法:guards。即使用bool表達式判斷是否符合條件,符合則執行該行。

fact :: Integer -> Integer
fact n
    | n < 0   = 0
    | n == 0 = 1 
    | otherwise = n * fact (n - 1)

 

 

高階函數higher order functions

  參數和返回值都是正常的數據類型則該函數是一階函數(first order)。以別的函數作為參數或者以其他函數作為返回結果則是高階函數(higher order)。如:

twice :: (a -> a) -> a -> a
twice f x = f (f x)

 

函數是一次接收一個函數進行處理的,比如一個需要2個參數的函數 ,如果只給出第一個參數,那么返回的是一個需要一個參數來完成原函數的新函數(partial application)。

prod :: Integer -> Integer ->Integer
prod x y = x * y

g = prod 4
p = g 6
q = twice g 3

 

條件表達式conditional expressions

樣式:

if Boolean_expression then exp1 else exp2   --then和else都必須要有,exp1和exp2的type一樣。

局部變量local variables: let Expressions

  當某個固定式子被多次使用時,為了方便可以定義為局部變量。

  樣式:

    let  equation

      equation

      ...

      equation

    in expression

  上式的值為in后的expression。以求一元二次方程程序為例,要注意Tab縮進:

quadratic :: Double -> Double -> Double -> (Double, Double)
quadratic a b c = 
    let d = sqrt (b^2 - 4 * a * c)
        x1 = (-b + d) / (2 * a)
        x2 = (-b -d) / (2 * a)
    in (x1, x2)

 要注意從let到in expression,其整體就是一個表達式,如下所示:

let x = sqrt 9 in (x + 1) * (x - 1)的值為8.0(x的值為3.0),所以2 + let x = sqrt 9 in (x + 1) * (x - 1)的值為10.0。

case

 

 

局部變量local variables: where

  另一種表達局部變量作為helper是where。如:

  maximum :: [Int] -> Int

  maximum [x] = x
  maximum (x:xs)
    | x > maxxs = x
    | otherwise = maxxs
    where maxxs = maximum xs

類型變量type variables

  類似與Java中的泛型generics,在定義函數時不明確其類型,在應用時,根據傳入參數的類型確定,這樣就只要定義一個函數就可以應對多種不同類型,而不用為了類型不同,一一重復定義函數,體現了其多態性,在之前的例子中也有沒有指明其類型而是用字母代替的,比如

fst :: (a, b) -> a
snd :: (a, b) -> b

 類型變量必須以小寫字母開頭,通常用a,b...


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM