Guest User

Untitled

a guest
Aug 15th, 2018
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.26 KB | None | 0 0
  1. {-# OPTIONS_GHC -fplugin-opt GHC.TypeLits.Normalise:allow-negated-numbers #-}
  2.  
  3. {-# LANGUAGE AllowAmbiguousTypes #-}
  4. {-# LANGUAGE FlexibleInstances #-}
  5. {-# LANGUAGE FunctionalDependencies #-}
  6. {-# LANGUAGE GADTs #-}
  7. {-# LANGUAGE MultiParamTypeClasses #-}
  8. {-# LANGUAGE PolyKinds #-}
  9. {-# LANGUAGE ScopedTypeVariables #-}
  10. {-# LANGUAGE TypeApplications #-}
  11. {-# LANGUAGE TypeFamilies #-}
  12. {-# LANGUAGE TypeInType #-}
  13. {-# LANGUAGE TypeOperators #-}
  14. {-# LANGUAGE UndecidableInstances #-}
  15. module HTree.Types where
  16.  
  17. import Data.Kind (Type)
  18. import GHC.TypeLits
  19. import Utils (CmpType, If, Max, Min)
  20.  
  21. data Tree (count :: Nat) (element :: Type) where
  22. Leaf :: Tree 0 element
  23.  
  24. Node :: Tree m element
  25. -> element
  26. -> Tree n element
  27. -> Tree (1 + m + n) element
  28.  
  29. data HTree (structure :: Tree (count :: Nat) Type) where
  30. HLeaf :: HTree 'Leaf
  31.  
  32. HNode :: HTree left -> centre -> HTree right
  33. -> HTree ('Node left centre right)
  34.  
  35. data Weight
  36. = LeftHeavy
  37. | Balanced
  38. | RightHeavy
  39.  
  40. type family Factor (left :: Nat) (right :: Nat) :: Weight where
  41. Factor 0 0 = Balanced
  42. Factor 1 0 = Balanced
  43. Factor 0 1 = Balanced
  44. Factor _ 0 = LeftHeavy
  45. Factor 0 _ = RightHeavy
  46. Factor left right
  47. = Factor (left - Min left right)
  48. (right - Min left right)
  49.  
  50. -- Balance by count, not height - maybe not the best idea for
  51. -- performance?
  52. class Balance
  53. (input :: Tree (count :: Nat) Type)
  54. (output :: Tree count Type) where
  55. balance :: HTree input -> HTree output
  56.  
  57. instance {-# OVERLAPPING #-} Balance 'Leaf 'Leaf where
  58. balance = id
  59.  
  60. instance
  61. ( input ~ 'Node left centre right
  62. , output ~ 'Node left' centre' right'
  63. , weight ~ Factor leftcount rightcount
  64. , BalanceLoop weight input output
  65. )
  66. => Balance
  67. ( 'Node (left :: Tree leftcount Type)
  68. centre
  69. (right :: Tree rightcount Type)
  70. )
  71. ( 'Node (left' :: Tree leftcount Type)
  72. centre'
  73. (right' :: Tree rightcount Type)
  74. ) where
  75. balance = balanceLoop @_ @weight @input @output
  76.  
  77. class BalanceLoop
  78. (weight :: Weight)
  79. (input :: Tree (count :: Nat) Type)
  80. (output :: Tree count Type) where
  81. balanceLoop :: HTree input -> HTree output
  82.  
  83. instance BalanceLoop 'Balanced noop noop where
  84. balanceLoop = id
  85.  
  86. instance
  87. ( Insert centre right right'
  88. , PopMax left centre' left'
  89. )
  90. => BalanceLoop LeftHeavy ('Node left centre right )
  91. ('Node left' centre' right') where
  92. balanceLoop (HNode left centre right)
  93. = HNode left' centre' (insert centre right)
  94. where (centre', left') = popMax left
  95.  
  96. instance
  97. ( Insert centre left left'
  98. , PopMin right centre' right'
  99. )
  100. => BalanceLoop RightHeavy ('Node left centre right )
  101. ('Node left' centre' right') where
  102. balanceLoop (HNode left centre right)
  103. = HNode (insert centre left) centre' right'
  104. where (centre', right') = popMin right
  105.  
  106. -- Still writing all these bits, don't look too closely...
  107.  
  108. class PopMax
  109. (input :: Tree count Type)
  110. (max :: Type)
  111. (output :: Tree (count - 1) Type) where
  112. popMax :: HTree input -> (max, HTree output)
  113.  
  114. instance {-# OVERLAPPING #-} PopMax ('Node left centre 'Leaf) centre left where
  115. popMax (HNode left centre HLeaf) = (centre, left)
  116.  
  117. instance PopMax right biggest right'
  118. => PopMax ('Node left centre right) biggest ('Node left centre right') where
  119. popMax (HNode left centre HLeaf)
  120. = (centre, left)
  121.  
  122. class PopMin
  123. (input :: Tree count Type)
  124. (max :: Type)
  125. (output :: Tree (count - 1) Type) where
  126. popMin :: HTree input -> (max, HTree output)
  127.  
  128. instance {-# OVERLAPPING #-} PopMin ('Node 'Leaf centre right) centre right where
  129. popMin (HNode HLeaf centre right) = (centre, right)
  130.  
  131. instance PopMin left smallest left'
  132. => PopMin ('Node left centre right) smallest ('Node left' centre right) where
  133. popMin (HNode left centre HLeaf)
  134. = (centre, left)
  135.  
  136. class Insert
  137. (element :: Type)
  138. (input :: Tree count Type)
  139. (output :: Tree (count + 1) Type) where
  140. insert :: element -> HTree input -> HTree output
Add Comment
Please, Sign In to add comment