zhaw-fup/Exercises/exercise-3/Filesystem.hs

102 lines
3 KiB
Haskell

{-
Gegeben ist ein einfacher Datentyp für Verzeichnisstrukturen (Ordnerbäume).
Eine Verzeichnisstruktur besteht in diesem Modell entweder aus einem
einzelnen File (durch seinen Namen und Grösse gegeben), oder durch eine Liste
von Unterverzeichnissen.
-}
type Name = String
type FileSizeKB = Int
data FileSystem
= File Name FileSizeKB
| Dir Name [FileSystem]
deriving Show
example :: FileSystem
example = Dir "root"
[ Dir "desktop"
[ File "notes.txt" 87
, File "brochure.pdf" 581
]
, Dir "pictures"
[ Dir "holiday2019"
[ File "paris1.png" 2075
, File "paris2.png" 3017
]
, Dir "holiday2018"
[ File "rome1.jpg" 2075
, File "rome2.jpg" 4584
, File "rome3.png" 2075
, File "notes.txt" 112
]
]
]
{- Aufgabe:
implementieren Sie eine "allgemeine fold Funktion" wie in der Vorlesung
besprochen.
-}
filesystem :: (Name -> FileSizeKB -> b) -> (Name -> [b] -> b) -> FileSystem -> b
filesystem file dir fs = case fs of
Dir name items ->
dir name (map (filesystem file dir) items)
File name fileSize ->
file name fileSize
{-
Ausgehend von der Funktion 'filesystem' wollen wir nun konkrete Funktionen
implementieren, die uns im Umgang mit dem 'FileSystem' Typ nützlich
erscheinen.
-}
{- Grösse eines Verzeichnisses
Implementieren Sie die Funktion 'size', die die Grösse einer gegebenen
Verzeichnisstruktur zurück gibt. Verwenden Sie die Funktion 'filesystem'.
-}
size :: FileSystem -> Int
size = filesystem (\_ -> \fileSize -> fileSize) (\_ -> \sizes -> sum sizes)
-- >>> size example
-- 14606
--
{- Datei abfragen
Implementieren Sie die Funktion 'existsFile', die bei einer gegebenen
Verzeichnisstruktur zurück gibt, ob darin eine Datei mit dem mitgegebenen
Namen zu finden ist. Verwenden Sie die Funktion 'filesystem'.
-}
existsFile :: Name -> FileSystem -> Bool
existsFile name = filesystem
(\fileName -> \_ -> name == fileName)
(\_ -> \items -> or items)
-- >>> existsFile "rome1.jpg" example
-- True
--
{- Pfade
Ein Pfad ist eine Liste von Namen.
Beispiel: "/pictures/holiday2019/paris1.png" wäre
["pictures", "holiday2019", "paris1.png"]
-}
type Path = [Name]
{- Alle Pfade finden
Implementieren Sie die Funktion 'findAll' mit folgendem Verhalten:
Input: Dateiname, Verzeichnisstruktur
Rückgabe: Alle Pfade in der gegebenen Struktur, die auf eine Datei mit dem
gegebenen Namen zeigen.
Verwenden Sie auch hier die Funktion 'filesystem'.
-}
findAll :: Name -> FileSystem -> [Path]
findAll name = filesystem file dir
where
file :: Name -> Int -> [Path]
file n _ = if n == name then [[n]] else []
dir :: Name -> [[Path]] -> [Path]
dir n subs = map (n :) (concat subs)
-- >>> findAll "notes.txt" example
-- [["root","desktop","notes.txt"],["root","pictures","holiday2018","notes.txt"]]
--