Reputation: 37
I have custom type below:
-- (Int,Int,Int) = (Year, Month, Day)
type Birth = (Int, Int, Int)
type Book = String
data Author = Author Book Book Book Birth
I was thinking that (Q1) if there is a way to iterate over the property inside Author, which means a function
fun
applied to a Author
type will return Book
values separately. I have thought using
BookA :: Author -> Book
BookA (Author bkA _ _ _) = bkA
or case...of
statement to get all three books separately, but it is too redundant. Is there a way iterately or recursively?
Also, (Q2) how can I get the BirthDay in a single function insdead of these:
birth :: Author -> Birth
birth (Author _ _ _ birth) = birth
bDay :: Birth -> Int
bDay (_,_,bDay) = bDay
Thank you guys so much.
Upvotes: 1
Views: 203
Reputation: 477606
I was thinking that (Q1) if there is a way to iterate over the property inside
Author
(…)
Although you can do that with Data
, it here looks a bit overkill. You can here simply match the tree books, and return these in a list:
BookA :: Author -> [Book]
BookA (Author bkA bkB bkC _) = [bkA, bkB, bkC]
Here it makes more sense however to define a list of Book
s for an Author
, since now you basically say that each Author
has written exactly three books. By making a list, an Author
can have written, zero, one, or more books:
data Author = Author [Book] Birth
You can even use records syntax, and let Haskell write the getters for you:
data Author = Author { booksA :: [Book], birth :: Birth }
Also, (Q2) how can I get the BirthDay in a single function insdead of these (…)
You can use nested patterns, like:
bday :: Author -> Birth
bdayA (Author _ _ _ (_, _, bd)) = bd
But often in Haskell one makes small reusable functions that can be combined. If you thus define birth
and bDay
, like you did, you can define the birthday of an Author
with:
birth :: Author -> Birth
birth (Author _ _ _ birth) = birth
bDay :: Birth -> Int
bDay (_,_,bDay) = bDay
bDayA :: Author -> Int
bDayA = bDay . birth
Upvotes: 2
Reputation: 80890
Q1: You can get all three books at the same time by pattern matching, and then return them as a list:
books :: Author -> [Book]
books (Author a b c _) = [a, b, c]
But are you sure you want to define your Author
like that? What if an author has two books or four? Such author wouldn't fit your definition, would it?
As @WillemVanOnsem pointed out in the comments, a more robust definition would be to make Author
contain a list of Book
instead of three books separately:
data Author = Author [Book] Birth
Q2: You can compose the two functions you have:
authorBDay :: Author -> Int
authorBDay = bDay . birth
Or, alternatively, you can pattern match directly:
authorBDay :: Author -> Int
authorBDay (Author _ _ _ (_,_,d)) = d
Patterns can be nested. That's their primary point.
Upvotes: 3