型によるプログラミング 直積型と直和型 ブックストアの商品の拡張
入門Haskellプログラミング (Will Kurt(著)、株式会社クイープ(監修、翻訳)、翔泳社)のUNIT3(型によるプログラミング)、LESSON 16(直積型と直和型)、16.5(練習問題)Q16-1の解答を求めてみる。
コード
lesson/app/Main.hs
module Main where
import Lib
( items,
)
main :: IO ()
main = do
mapM_ print items
lesson/src/Lib.hs
module Lib
( items,
)
where
items :: [(String, Double)]
items = zip creators prices
storeItems :: [StoreItem]
storeItems =
[ BookItem $
Book
{ author = AuthorCreator $ Author $ Name "firstName" "lastName",
bookPrice = 10
},
RecordItem $
VinylRecord
{ artist =
ArtistCreator $
Person $
NameWithMiddle "firstName" "middleName" "lastName",
recordPrice = 20
},
ToyItem $
CollectibleToy
{ name = "toy",
toyPrice = 30
},
PamphletItem $
Pamphlet
{ title = "Title",
description = "Description",
email = "haskell@example.com"
}
]
creators :: [String]
creators = map madeBy storeItems
prices :: [Double]
prices = map price storeItems
type FirstName = String
type LastName = String
type MiddleName = String
data Name
= Name FirstName LastName
| NameWithMiddle FirstName MiddleName LastName
| TwoInitialsWithLast Char Char LastName
deriving (Show)
data Author = Author Name deriving (Show)
data Artist = Person Name | Band String deriving (Show)
data Creator
= AuthorCreator Author
| ArtistCreator Artist
deriving (Show)
data Book = Book
{ author :: Creator,
bookPrice :: Double
}
data VinylRecord = VinylRecord
{ artist :: Creator,
recordPrice :: Double
}
data CollectibleToy = CollectibleToy
{ name :: String,
toyPrice :: Double
}
data Pamphlet = Pamphlet
{ title :: String,
description :: String,
email :: String
}
data StoreItem
= BookItem Book
| RecordItem VinylRecord
| ToyItem CollectibleToy
| PamphletItem Pamphlet
price :: StoreItem -> Double
price (BookItem book) = bookPrice book
price (RecordItem record) = recordPrice record
price (ToyItem toy) = toyPrice toy
price (PamphletItem _) = 0
madeBy :: StoreItem -> String
madeBy (BookItem book) = show $ author book
madeBy (RecordItem vinylRecord) = show $ artist vinylRecord
madeBy (PamphletItem pamphlet) = title pamphlet
madeBy _ = "unknown"
入出力結果(Terminal, Zsh)
% stack exec lesson-exe
("AuthorCreator (Author (Name \"firstName\" \"lastName\"))",10.0)
("ArtistCreator (Person (NameWithMiddle \"firstName\" \"middleName\" \"lastName\"))",20.0)
("unknown",30.0)
("Title",0.0)
%