Haskell - 一种类型的访问字段

Eri*_*tos 1 haskell types

我在Haskell中创建了一个类型,但我不知道如何获取我创建的类型的一个字段.我该怎么办?我应该做一个功能Book -> String还是那样的?

import Data.List
import System.IO


type Book = (Int, String, String, String, String, String, String)



bookNew :: Int -> String -> String-> String -> String -> String -> String -> Book
bookNew isbn title author genre date publisher summary =
   (isbn,title,author,genre,date,publisher,summary):: Book 


main = do
   let book = bookNew 1 "title" "author" "genre" "date" "publisher" "summary"
   --Access title of "book" somehow
   return book
Run Code Online (Sandbox Code Playgroud)

Jus*_*ood 9

我建议在创建这么大的类型时使用记录.有点像

data Book = Book { pages  :: Int
                 , author :: String
                 , title  :: String
                 }
Run Code Online (Sandbox Code Playgroud)

在这一点上,如果你想要一本书的作者,那就简单了

main = do
  let book = Book 20 "me" "my book"
  putStrLn (author book)
Run Code Online (Sandbox Code Playgroud)

这将打印您的书的作者.

记录本质上创建的功能只从您的类型中提取单个数据.


Kap*_*pol 5

如果要使用类型同义词,则必须手动创建函数来检索Book类型的每个“字段” :

getTitle :: Book -> String
getTitle (_, title, _, _, _, _, _) = title
Run Code Online (Sandbox Code Playgroud)

我建议您使用记录语法创建自己的数据类型以免费获得此类功能。

此外,在创建此类复杂类型的同义词时,您可以创建其他同义词来表示主要同义词的各个部分,以明确Book代表什么。

type Isbn = Int
type Title = String
type Author = String
type Genre = String
type Date = String 
type Publisher = String
type Summary = String

type Book = (Isbn, Title, Author, Genre, Date, Publisher, Summary)
Run Code Online (Sandbox Code Playgroud)

然后getTitle可以有类型Book -> Title

  • 甚至比类型同义词更好的是使用 `newtype`,这样 `Title`、`Author`、`Genre` 等不能相互替代。 (2认同)