we can make types whose constructors have fields that are of the same type! such as the trees where left child and right child are also a tree.
We are going to inspect one type which representst list, whch concatenate two list , one ias the listHead and one represents as the list tails. - the head could be a value.
Let's see the list type
data List a = Empty | Cons a (List a) deriving (Show, Read, Eq, Ord)
and you can find it easier to understand in the record syntax.
data List a = Empty | Cons { listHead :: a, listTail :: List a} deriving (Show, Read, Eq, Ord)
then we will see we can declare infix operator to use on the constructor
-- file
-- type_infixr_typecalss102.hs
-- description:
-- with the infixr operator define in the constructor
-- data List a = Empty | Cons a (List a) deriving (Show, Read, Eq, Ord)
data List a = Empty | Cons { listHead :: a, listTail :: List a} deriving (Show, Read, Eq, Ord)
-- ghci> Empty
-- Empty
-- ghci> 5 `Cons` Empty
-- Cons 5 Empty
-- ghci> 4 `Cons` (5 `Cons` Empty)
-- Cons 4 (Cons 5 Empty)
-- ghci> 3 `Cons` (4 `Cons` (5 `Cons` Empty))
-- Cons 3 (Cons 4 (Cons 5 Empty))
infixr 5 :-:
data List a = Empty | a :-: (List a) deriving (Show, Read, Eq, Ord)
-- ghci> 3 :-: 4 :-: 5 :-: Empty
-- (:-:) 3 ((:-:) 4 ((:-:) 5 Empty))
-- ghci> let a = 3 :-: 4 :-: 5 :-: Empty
-- ghci> 100 :-: a
-- (:-:) 100 ((:-:) 3 ((:-:) 4 ((:-:) 5 Empty)))
-- this is how the ++ is implemented for normal lists
infixr 5 ++
(++) :: [a] -> [a] -> [a]
[] ++ ys = ys
(x:xs) ++ ys = x : (xs ++ ys)
-- and we can define our .++ operation for our own list.
infixr 5 .++
(.++) :: List a -> List a -> List a
Empty .++ ys = ys
(x :-: xs) .++ ys = x :-: (xs .++ ys)
-- let's test it out
-- ghci> let a = 3 :-: 4 :-: 5 :-: Empty
-- ghci> let b = 6 :-: 7 :-: Empty
-- ghci> a .++ b
-- (:-:) 3 ((:-:) 4 ((:-:) 5 ((:-:) 6 ((:-:) 7 Empty))))
we then will examine a common data structure - the tree.
-- file
-- recursive_data_structure_tree.hs
-- description:
-- recursive data structure tree
data Tree a = EmptyTree | Node a (Tree a) (Tree a) deriving (Show, Read, Eq)
singleton :: a -> Tree a
singleton x = Node x EmptyTree EmptyTree
treeInsert :: (Ord a) => a -> Tree a -> Tree a
treeInsert x EmptyTree = singleton x
treeInsert x (Node a left right)
| x == a = Node x left right
| x < a = Node a (treeInsert x left) right
| x > a = Node a left (treeInsert x right)
treeElem :: (Ord a) => a -> Tree a -> Bool
treeElem x EmptyTree = False
treeElem x (Node a left right)
| x == a = True
| x < a = treeElem x left
| x > a = treeElem x right
-- checkstreeInsert works
-- ghci> let nums = [8,6,4,1,7,3,5]
-- ghci> let numsTree = foldr treeInsert EmptyTree nums
-- ghci> numsTree
-- Node 5 (Node 3 (Node 1 EmptyTree EmptyTree) (Node 4 EmptyTree EmptyTree)) (Node 7 (Node 6 EmptyTree EmptyTree) (Node 8 EmptyTree EmptyTree))
--
-- check that that the treeElem will works correctly
-- ghci> 8 `treeElem` numsTree
-- True
-- ghci> 100 `treeElem` numsTree
-- False
-- ghci> 1 `treeElem` numsTree
-- True
-- ghci> 10 `treeElem` numsTree
-- False
本文深入探讨了在类型构造器中使用同型操作符的方法,通过实例展示了如何创建复杂的类型结构,如列表与树,并详细说明了其在实际编程中的应用。
2313

被折叠的 条评论
为什么被折叠?



