Difference between revisions of "FP Laboratory 11"
Jump to navigation
Jump to search
Line 55: | Line 55: | ||
Container - Footer | Container - Footer | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
+ | <div class="mw-collapsible mw-collapsed" data-collapsetext="Hide solution" data-expandtext="Show solution"> | ||
+ | <syntaxhighlight lang="Haskell"> | ||
+ | instance Show Position where | ||
+ | show (Position (Point col row) width height) = "(" ++ show col ++ "," ++ show row ++ ")["++ show width++","++ show height++"]" | ||
+ | |||
+ | instance Show Component where | ||
+ | show :: Component -> String | ||
+ | show gui = showIndent "" gui where | ||
+ | showIndent ind (TextBox name position text) = ind ++ show position ++ " TextBox[" ++ name ++ "]: " ++ text ++"\n" | ||
+ | showIndent ind (Button name position text click) = ind ++ show position ++ " Button[" ++ name ++ "]: " ++ text ++"\n" | ||
+ | showIndent ind (Container name children) = let | ||
+ | inner = concat[showIndent (ind++"\t") c |c<-children] | ||
+ | in ind ++ "Container - " ++ name ++ "\n" ++ inner | ||
+ | </syntaxhighlight> | ||
+ | </div> | ||
+ | <div style="clear:both"></div> | ||
<translate> | <translate> |
Revision as of 12:07, 15 November 2023
Complex data structure
Consider following data structure representing some kind of GUI.
data Point = Point {column::Int,row::Int} deriving (Show)
data Event = MouseEvent Point
| KeyEvent {keyPressed::Char} deriving (Show)
data Position = Position {leftTopCorner :: Point, width :: Int, height :: Int}
data Component
= TextBox {name :: String, position :: Position, text :: String}
| Button {name :: String, position :: Position, text :: String, onClick :: Maybe ((Event, Component) -> String)}
| Container {name :: String, children :: [Component]}
As an example, we can use following data structure.
gui :: Component
gui =
Container
"My App"
[ Container
"Menu"
[ Button "btn_new" (Position (Point 0 0) 100 20) "New" Nothing,
Button "btn_open" (Position (Point 100 0) 100 20) "Open" Nothing,
Button "btn_close" (Position (Point 200 0) 100 20) "Close" Nothing
],
Container "Body" [TextBox "textbox_1" (Position (Point 0 20) 300 500) "Some text goes here"],
Container "Footer" []
]
- Add the data type
Component
into the type classShow
.
The result for our data from previous example should be something like this.
ghci> gui
Container - My App
Container - Menu
(0,0)[100,20] Button[btn_new]: New
(100,0)[100,20] Button[btn_open]: Open
(200,0)[100,20] Button[btn_close]: Close
Container - Body
(0,20)[300,500] TextBox[textbox_1]: Some text goes here
Container - Footer
instance Show Position where
show (Position (Point col row) width height) = "(" ++ show col ++ "," ++ show row ++ ")["++ show width++","++ show height++"]"
instance Show Component where
show :: Component -> String
show gui = showIndent "" gui where
showIndent ind (TextBox name position text) = ind ++ show position ++ " TextBox[" ++ name ++ "]: " ++ text ++"\n"
showIndent ind (Button name position text click) = ind ++ show position ++ " Button[" ++ name ++ "]: " ++ text ++"\n"
showIndent ind (Container name children) = let
inner = concat[showIndent (ind++"\t") c |c<-children]
in ind ++ "Container - " ++ name ++ "\n" ++ inner
Additional exercises
- Consider the following definition and the example of the m-ary tree.
data MTree a = MTree a [MTree a]
testTree1 :: MTree Int
testTree1 = MTree 1 [(MTree 2 [(MTree 3 []),(MTree 4 [(MTree 5 []),(MTree 6 [])]), (MTree 7 []),(MTree 8 [])]), (MTree 9 [])]
- Create a function that sums all values stored in the m-ary tree.
msum :: MTree Int -> Int
- Create a function that extracts all values from the m-ary tree into a list.
mToList :: MTree a -> [a]
- Create a function that counts all leaves in the m-ary tree.
mLeafCount :: MTree a -> Int
- Create a function that finds a maximum value stored in the m-ary tree.
mMaxTree :: Ord a => MTree a -> a
- Create a function that checks whether a given element is stored in the m-ary tree.
mContains :: Eq a => MTree a -> a -> Bool
- Create a function that returns a number of elements greater than a given value.
mGreaterThan :: Ord a => MTree a -> a -> Int