basic Haskell : searching through multiple lists for the same elements -
i've been battling problem while. i'm trying create "organisation" list of gyms. these gyms list of people. each person has id number, age , amount of credit.
i want findid function search through organisation search through list of gyms find users inputted id , return total of credit. however, feel i'm overcomplcating problem , struggling now.
newtype id = id int deriving (show) newtype age = age int deriving (show) newtype credit = credit int deriving (show) newtype person = person (id, age, weight) deriving (show) type gym = [person] type organisation = [gym] getage :: person -> int getage (person(a,age b,c)) = b getid :: person -> int getid (person(id a,b,c)) = getcredit :: person -> int getcredit (person(a,b,credit c)) = c p = person ( id 123, age 65, credit 12000) q = person ( id 321, age 64, credit 0) e = person ( id 453, age 30, credit 3000) r = person ( id 123, age 65, credit 2310) s = person ( id 364, age 32, credit 32340) t = person ( id 123, age 65, credit 1300) org1 = [p,q,e] org2 = [r,s,t] hasperson :: gym->int-> bool hasperson gym' id' = not (null(filter hasperson' gym') ) hasperson' person' = getid person' == id' findid:: id -> organisation -> int findid id' org = total isingym org' = hasperson ( org' id' ) validgym = filter (isingym) org' total = sum ( map getcredit validgym)
first, recommend using record represent person, unless have particular reason assign new type each field:
type id = int type age = int type credit = int data person = person { personid :: id , personage :: age , personcredit :: credit } deriving (eq, show) type gym = [person] type organization = [gym]
next, can use map
convert gym
[int]
personid
, can use built-in elem
check if id given appears in list.
hasperson :: gym -> id -> bool hasperson gym pid = pid `elem` map personid gym
now, findid
function, suggest renaming organizationcredit
, , make simpler function called gymcredit
calculate single gym:
gymcredit :: id -> gym -> credit gymcredit pid gym = sum $ map personcredit $ filter (\p -> personid p == pid) gym organizationcredit :: id -> organization -> credit organizationcredit pid org = sum $ map (gymcredit pid) org
alternatively, declare functions as
gymcredit :: person -> gym -> credit gymcredit person gym = sum $ map personcredit $ filter (\p -> personid p == pid) gym pid = personid person organizationcredit :: person -> organization -> credit organizationcredit person org = sum $ map (gymcredit person) org
edit: stick old types, have define few functions yourself, put them in code need to
newtype id = id int deriving (eq, show) newtype age = age int deriving (eq, show) newtype credit = credit int deriving (eq, show) newtype person = person (id, age, credit) deriving (eq, show) type gym = [person] type organisation = [gym] personid :: person -> id personid (person (i, a, c)) = personage :: person -> age personage (person (i, a, c)) = personcredit :: person -> credit personcredit (person (i, a, c)) = c idval :: id -> int idval (id x) = x ageval :: age -> int ageval (age x) = x creditval :: credit -> int creditval (credit x) = x gymcredit :: person -> gym -> credit gymcredit person gym = credit $ sum $ map (creditval . personcredit) $ filter (\p -> personid p == pid) gym pid = personid person organisationcredit :: person -> organisation -> credit organisationcredit person org = credit $ sum $ map (creditval . gymcredit person) org
it important note i've added eq
list of derived typeclasses each newtype. without it, wouldn't able directly compare 2 id
s, you'd have extract values first. important typeclass derive ord
, lets use <
, >
, <=
, , >=
operators, whole bunch of list functions sort
.
Comments
Post a Comment