Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| fp:lab10 [2021/05/13 14:50] pdmatei created | fp:lab10 [2021/05/20 13:32] (current) lfa | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ===== 9.3. Trees ===== | + | ===== 10. Trees ===== | 
| + | |||
| + | File systems are one common application that uses a tree representation. We define the following data type to model a very simplistic file system: | ||
| - | 9.3.1. Implement a datatype for trees of integers. Write a function which checks if a tree is complete: | ||
| <code haskell> | <code haskell> | ||
| - | isComplete :: IntTree -> Bool | + | data FTree = Dir String [FTree] | File String deriving (Show, Eq) | 
| </code> | </code> | ||
| - | 9.3.2. Write a function which flattens a tree to a list: | + | <note tip> | 
| + | The ''deriving (Show, Eq)'' at the end offer a default enrollment into the ''Show'' and ''Eq'' type classes, which allows us to represent our filesystem as a string using ''show'' and to compare two filesystems using ''=='' and ''/=''. | ||
| + | </note> | ||
| + | |||
| + | Each node is a filesystem entry; directory nodes have a name and a list of children (its contents: other directories or files) and regular files are leaves (no children) characterized by their name. | ||
| + | |||
| + | Here is an example filesystem instance: | ||
| <code haskell> | <code haskell> | ||
| - | flatten :: IntTree -> [Integer] | + | t = Dir "/" [Dir "usr" [Dir "share" [], | 
| + | Dir "var" [], | ||
| + | Dir "include" [File "stdio.h", File "string.h", File "stdlib.h"]], | ||
| + | Dir "dev" [File "sda", File "sda1", File "sda2"], | ||
| + | Dir "etc" [File "sudoers", File "passwd", File "shadow"], | ||
| + | Dir "home" [Dir "mihai" [File ".zshrc", Dir "sol" [File "Lab10.hs"]], | ||
| + | Dir "student" [File ".bashrc", Dir "sol" []]]] | ||
| </code> | </code> | ||
| - | 9.3.3. The game Tic-Tac-Toe (or X and 0) is played on a three-by-three board of **positions**. Each position may be: free, with an X or with a 0. | + | We also define a ''Path'' to be a list of names, representing a way through the tree, from the root to a particular node. | 
| - | * write a ADT ''Position'' which encodes the value of each position. | + | |
| - | * write an ADT ''Board'' which encodes (using matrices) a 3-by-3 board of positions. | + | |
| - | * write a function which checks if either '''X''' or '''0''' have won (''won :: Char -> Board -> Bool'') | + | |
| - | Starting from a given (initial) board, we want to build **a tree** of all possible outcomes of the game. Example: | + | <code haskell> | 
| + | type Path = [String] | ||
| - | <code> | + | path1 = ["/", "usr", "include", "stdio.h"] | 
| - | Parent node: | + | path2 = ["/", "home", "student"] | 
| + | wrongPath1 = ["/", "usr", "include", "math.h"] | ||
| + | wrongPath2 = ["/", "sbin"] | ||
| + | </code> | ||
| - | X 0 0 | + | 10.1 Write a function ''countFiles :: FTree -> Int'' that counts how many regular files are there in a filesystem. | 
| - | 0 X | + | |
| - | 0 | + | |
| - | Children (It is X-s turn to move): | + | 10.2 Write a function ''longestPath :: FTree -> Int'' which gives the length of the longest path in the filesystem. | 
| - | X 0 0 X 0 0 X 0 0 | + | 10.3 Write a function ''findEntry :: String -> FTree -> Bool'' which takes the name of an entry (dir or file) and a filesystem and determines whether that entry can be found in the filesystem. | 
| - | 0 X X 0 X  0  X | + | |
| - | 0  X 0 0 X | + | 10.4 Write a function ''checkExists :: Path -> FTree -> Bool'' which takes a path and a filesystem and determines whether there exists an entry with that path. | 
| - | </code> | + | |
| + | 10.5 Write a function ''checkIsFile :: Path -> FTree -> Bool'' which takes a path and a filesystem and determines whether there exists a **regular file** with that path (if the path exists, but it's a dir, the result should be ''False''). | ||
| + | |||
| + | 10.6 Write a function ''checkIsDir :: Path -> FTree -> Bool'' which takes a path and a filesystem and determines whether there exists a **directory** with that path (if the path exists, but it's a regular file, the result should be ''False''). | ||
| + | |||
| + | 10.7 Write a function ''touch :: Path -> FTree -> FTree'' which takes a path and a filesystem and produces a new filesystem. If the path existed in the original, nothing changes. If the path didn't exist in the original, the new filesystem will contain a regular file at that path. | ||
| + | |||
| + | 10.8 Write a function ''mkdir :: Path -> FTree -> FTree'' which takes a path and a filesystem and produces a new filesystem. If the path existed in the original, nothing changes. If the path didn't exist in the original, the new filesystem will contain a directory at that path. | ||
| + | |||
| + | 10.9 Write a function ''rm :: Path -> FTree -> FTree'' which takes a path and a filesystem and produces a new filesystem without the entry at that path. | ||
| + | 10.10 Write a function ''longestPath2 :: FTree -> Path'' which takes a filesystem and returns the longest path. | ||
| - | 9.3.4. | + | 10.11 Write a function ''findEntry2 :: String -> FTree -> Path'' which takes the name of an entry (dir or file) and a filesystem and determines whether that entry can be found in the filesystem. If it doesn't exist, an empty path ''[]'' is returned. |