Extract the two recorded parents from every matching certificate, and use duplicate removal so that repeated certificates do not repeat an individual. This helper is shared by the remaining Haskell definitions:
unique :: Eq a => [a] -> [a]
unique [] = []
unique (x:xs) = x : unique [y | y <- xs, y /= x]
parents :: Database -> Person -> [Person]
parents db p = unique [q | (baby,mother,father) <- db,
baby == p, q <- [mother,father]]A person need not have a certificate of their own to appear in the output: a parental field is already evidence of the relationship. The resulting list preserves first occurrence order, with mother before father in each certificate. Its set of entries is
children :: Database -> Person -> [Person]
children db p = unique [baby | (baby,mother,father) <- db,
mother == p || father == p]Duplicate removal handles repeated certificates and children recorded in more than one matching row. ThusThe displayed set describes membership; the implementation returns its entries as a list in first certificate order.
Treat brothers as male individuals sharing at least one recorded parent, including half-brothers. Derive a sibling helper and then select the recorded sex:
siblings :: Database -> Person -> [Person]
siblings db p = unique [q | parent <- parents db p,
q <- children db parent, q /= p]
brothers :: Database -> Person -> [Person]
brothers db p = [q | q <- siblings db p, sex q == Male]The exclusion
q /= p prevents a male individual from being his own brother. Duplicate removal is needed because a full brother can be found through both parents. The membership condition isIf the intended convention is full brothers only, replace the shared-parent condition by a common mother and a common father in the recorded certificates. The definition above states the convention explicitly rather than silently discarding half-brothers.Use first cousins: the children of the siblings of a recorded parent. This includes cousins through a parent's half-sibling under the convention above. In Haskell:
cousins :: Database -> Person -> [Person]
cousins db p = unique [q | parent <- parents db p,
auntOrUncle <- siblings db parent,
q <- children db auntOrUncle, q /= p]Selecting siblings of parents avoids the mistake of returning all people with a common grandparent, which would also return ordinary siblings. The explicit exclusion of
p is harmless on an ordinary consistent pedigree and prevents a self-result in unusual records. Multiple relationship paths give just one output entry after duplicate removal. Thus Articles by others on the same topic
There are currently no matching articles.