103 lines
3 KiB
Haskell
103 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"]]
|
|
--
|