简体   繁体   中英

Iterating over a custom type and access the property inside in haskell

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.

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.

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  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

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 = 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM