Zunächst: sorry für die mehrdeutig Frage Titel ... Zweitens: Ich bin ein komplette Anfänger ...Funktionsmuster Spiel auf Daten Argument abhängig
Ich habe einen sehr einfachen Datentyp namens Aufgabe. Eine Aufgabe hatte einen Preis, eine Menge und eine Einheit. Die Einheit kann Tage oder Stunden umfassen.
Ich möchte den Gesamtbetrag und Gesamtpreis für eine Liste von Aufgaben berechnen. Für den Preis gibt es kein Problem, ich multipliziere jeden Preis mit dem Betrag für die gegebene Aufgabe und es summiert sich. Aber für die Menge bin ich fest.
Ich kann nicht einfach eine Liste von Stunden und Tagen falten. Sagen wir, ich habe eine Aufgabe mit 1 Stunde und eine mit 1 Tag, beide haben eine Menge von 1, aber die Summe sollte in einer Einheit sein. Ich habe 'Stunde' als Basiseinheit gewählt.
So zu rekapitulieren, das ist meine Art:
-- data --
-- the task is parsed from json, but I would like the `unit` type to be
-- custom like `Hour | Day` instead of String. But that is an aeson issue?
data Task = {
amount :: Double,
price :: Double,
unit :: String
}
-- functions --
taskPrice :: Task -> Double
taskPrice t = fromIntegral (price t) * amount t
calcPrice :: [Task] -> Double
calcPrice [] = 0
calcPrice [x] = taskPrice x
calcPrice (x:xs) = foldl (\acc x -> acc + (taskPrice x)) (taskPrice x) xs
-- this version will add days and hours like they are equal...
calcInvoiceHours :: [Task] -> Double
calcInvoiceHours [] = 0
calcInvoiceHours [x] = amount x
calcInvoiceHours (x:xs) = foldl (\acc x -> acc + (amount x)) (amount x) xs
Jede Aufgabe kennt seine eigene Art, sondern ein Schaltergehäuse innerhalb des Musterabgleich ist nicht die Art, wie ich denke, zu gehen ... In einigen naiver Pseudo-Code würde ich schreiben:
calcInvoiceHours :: [Task] -> Double
calcInvoiceHours [] = 0
calcInvoiceHours [x -> unit x === Hour] = amount x
calcInvoiceHours [x -> unit x === Day] = (amount x) * 8 -- work 8 hours a day
calcInvoiceHours (x:xs) = foldl (\acc x -> acc + (amount x)) (amount x)
ich weiß dies falsch ist, aber ich weiß nicht, wie es zu tun. Ich könnte laufen, bevor ich hier laufen kann, aber es scheint so eine einfache Aufgabe (kein Wortspiel beabsichtigt).
Danke!
== == UPDATE
fand ich einen Weg! Aber wenn das nicht der richtige Weg ist, würde ich mich freuen zu hören, wie ich mich verbessern kann! Außerdem suche ich noch die Stunden und Tage der Strings zu einem konkreten Kunden-Typ zu analysieren Tag von Json.
taskHours :: Task -> Double
taskHours (Task _ amount _ unit)
| unit == "hours" = amount
| otherwise = amount * 8
calcInvoiceHours :: [Task] -> Double
calcInvoiceHours [] = 0
calcInvoiceHours [x] = taskHours x
calcInvoiceHours (x:xs) = foldl (\acc x -> acc + (taskHours x)) (taskHours x) xs
Sind Sie mit [sum types] (https://www.schoolofhaskell.com/school/to-infinity-and-beyond/pick-of-the-week/sum-types)? –
Nein, ich bereite gerade die Dokumentation vor, danke! Ich könnte es mit dem Update oben und auch mit dem Vorschlag unten arbeiten lassen. –
Vielleicht wäre diese Frage besser für [Code Review] (http://codereview.stackexchange.com/) geeignet? –