F#個人學習筆記3(F# survey)

1、F#自定義類型,自定義類型可以將我們所需的值打包成一個類型整體,如 Student類型包含{int id ; string name}。F#自定義類型可以通過tuple(元組)或record記錄來實現自定義類型。
    a、在一些臨時的情況下我們可以直接用元組來組合一些值 ,但這僅僅是將值進行組合,不能靈活的訪問想要的信息,也沒有專有類型名稱
      將編號和姓名打包成元組由標識符userinfo來引用
      let userinfo = ( 1 , "張三" )
      let id , name = userinfo //由id 和 name 來引用用戶信息 , id = 1  name = "張三"
      printfn "%i %s" id name
    b、用元組來聲明類型, 關鍵字type。如 type userinfo = int * string * int ,聲明瞭類型userinfo 它包含兩個整型成員和一個字符串成員。這種方式可以給組合的信息起有類型名稱(通常叫它是類型組合別名或類型別名)
      type userinfotype = int * string * int //用戶信息類型由整型  字符串 整型組成
      let user : userinfotype = ( 1 , "abc" , 1) //聲明標識符user爲( 1 , "abc" , 1) ,但你不知道其中哪個1代表編號id
      printfn "%s" ((fun (u : userinfotype) ->    //聲明臨時方法來將userinfotype對象變成字符串 , 這個fun方法在一行書寫時(fun (u : userinfotype) ->let id , name , age = u ;in Printf.sprintf "id:%i;name: %s ;age:% i" id name age;) user
                      let id , name , age = u ;
                      Printf.sprintf "id:%i;name: %s ;age:% i" id name age;) user)
    c、用record來聲明類型,用record來聲明類型和元組一樣可以將幾個類型的元素組合成一個新類型,但不同的是record中的字段是有名稱的。record和javascript中的json對象頗有幾分相像。
      type userinfo = { Id : int ; Name : string ; Age : int }
      let user = { Id = 1 ; Name = "張三" ; Age = 20 }
      printfn "%s" (user.GetType().Name) //結果是userinfo ,在標識符user綁定對象時,系統僅僅根據對象中成員名稱(非成員類型)在已經存在的類型中查找匹配的者,所以匹配的類型是userinfo。但是根據成員名稱匹配是會有衝的。
      
      type userinfo = { Id : int ; Name : string ; Age : int }
      type userinfo2 = { Id : int ; Name : string ; Age : int }
      let user = { Id = 1 ; Name = "張三" ; Age = 20 }
      printfn "%s" (user.GetType().Name) //結果是userinfo2,在衝突情況下,匹配最後一個符合的情況,所以是userinfo2。如果type userinfo2 = { Id : int ; Name : int ; Age : int } 系統還是會去匹配userinfo2,原因是和成員類型無關,因爲Name的類型和"張三"值類型不匹配,這裏會有語法錯誤。
      
      type userinfo = { Id : int ; Name : string ; Age : int }
      type userinfo2 = { Id : int ; Name : string ; Age : int }
      let ( user : userinfo ) = { Id = 1 ; Name = "張三" ; Age = 20 } //可以添加類型約束來指定對象類型
      //或 let user = { Id = 1 ; Name = "張三" ; Age = 20 } : userinfo
      printfn "%s" (user.GetType().Name) //結果是userinfo
      
      注: let user2 = { new userinfo with Id = 2 and Name = "李四" and Age = 20} 這種寫法過期,按編譯器提示可以使用member關鍵字來爲成員賦值,但具體語法如何暫不知道,有待求解。

 
     d、聯合類型,感覺上有點類似泛化的意思,但子類型並未有繼承,繼承是從上往下,而聯合類型是從子類出發找個父類型(個人理解,請指證)

      type Num = //定義聯合類型Num,成員類型分別是Num.Int : int->Num , Num.Float : float -> Num , Num.Double : double -> Num
          | Int of int
          | Float of float
          | Double of double
      let i = Int 1  //聲明標識符 i 並綁定值 1 : Int
      let printType  i = //進行模式匹配 , 這兒是進行類型匹配
          match i with
          | Int i -> printfn "%s" "Int"
          | Float i -> printfn "%s" "Float"
          | Double i -> printfn "%s" "Double"
      
     聯合類型在聲明時可以用未指明的子類型,通過類型參數化來實現。類型參數有兩種實現方式。用'開頭加參數名的方式來聲明類型參數,參數具體指代的類型在創建聯合類型對象時推斷確定。
        type 'v Tree =  //在type和聯合類型之間聲明類型參數,這種方式聲明類型參數個數只能有一個。需要多個類型參數時可以用下面一種方式。
            | TreeNode of 'v Tree * 'v Tree 
            | TreeNodeValue of 'v
        let tree =
            TreeNode (TreeNodeValue "leftRoot",
                TreeNode ( TreeNodeValue "rightChild1" , TreeNodeValue "rightChild2")
            )
        printfn "%A" tree 
        
        type TreeView<'l,'r> = //在聯合類型後有尖括號的方式來聲明類型參數,這種方式有點像泛型的寫法。
            |TreeNode of TreeView<'l,'r> * TreeView<'l,'r>
            |TreeValue of 'l * 'r
        let tree2 = 
            TreeNode ( TreeValue (1,"a") , 
                TreeNode ( TreeValue (2 , "b") , TreeValue ( 3 , "c" ))) 
        printfn "%A" tree2
        
        type binarytree<'v> = //一個二叉樹的例子
            | TreeNode of binarytree<'v> * 'v * binarytree<'v>
            | NullNode of 'v
        let btree =
            TreeNode ( NullNode null , "a" , TreeNode ( TreeNode ( NullNode null , "c" , NullNode null ) , "b" , NullNode null))
        let rec printbtree t= //用遞歸來遍歷樹
            match t with
            | TreeNode (leftnode , value , rightnode) ->  printbtree leftnode ; printbtree rightnode ;printf "%s " value ;//後序遍歷
            | NullNode v -> printf "%s" ""
        printbtree btree
      
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章