Haskell - 格式化问题

use*_*649 2 database formatting haskell function higher-order-functions

这是我必须显示一个有价值信息数据库的当前代码,但是当打印出来时,阅读它并不是很清楚.

type Title = String
type Cast = String
type Year = Int
type Fans = String

type Film = (Title, [Cast], Year, [Fans])
type Database = [Film]

testDatabase :: Database
testDatabase = [("Casino Royale", ["Daniel Craig", "Eva Green", "Judi Dench"], 2006, ["Garry", "Dave", "Zoe", "Kevin", "Emma"]),
    ("Cowboys & Aliens", ["Harrison Ford", "Daniel Craig", "Olivia Wilde"], 2011, ["Bill", "Jo", "Garry", "Kevin", "Olga", "Liz"]),     
        ("Catch Me If You Can", ["Leonardo DiCaprio", "Tom Hanks"], 2002, ["Zoe", "Heidi", "Jo", "Emma", "Liz", "Sam", "Olga", "Kevin", "Tim"])]      
Run Code Online (Sandbox Code Playgroud)

运行此功能时:

displayAllFilms :: Database ->[(Title, [Cast], Year, [Fans])]
displayAllFilms [] = []
displayAllFilms ((i, j, k, l): xs)
        |l == [] = (i, j, k, []) : displayAllFilms xs
        |otherwise = (i, j, k, l) : displayAllFilms xs
Run Code Online (Sandbox Code Playgroud)

它打印这个:

[("皇家赌场",["丹尼尔克雷格","伊娃格林","朱迪丹奇"],2006 ["加里","戴夫","佐伊","凯文","艾玛"]),(" "牛仔与外星人","哈里森·福特","丹尼尔·克雷格","奥利维亚·王尔德",2011年,["比尔","乔","加里","凯文","奥尔加","利兹"]) ,("抓住我,如果你能",["莱昂纳多迪卡普里奥","汤姆汉克斯"],2002年,["佐伊","海蒂","乔","艾玛","莉兹","山姆","奥尔加", "凯文", "蒂姆")]

这显然是不可读的:有没有办法让每个电影信息(在这种情况下)打印在单独的行,即.使用/ n表示法?

非常感谢帮助,谢谢!:)

dav*_*420 5

displayAllFilms :: Database -> IO ()
displayAllFilms db = mapM_ print db
Run Code Online (Sandbox Code Playgroud)

这是如何运作的?

  • print 被定义为

    print :: Show a => a -> IO ()
    print x = putStrLn (show x)
    
    Run Code Online (Sandbox Code Playgroud)
  • 怎么解释mapM_?...你知道是什么map,是吗?给定函数和列表,它将函数应用于列表的每个元素,并返回结果列表.

    map采用类型的函数a -> b,但mapM_采用类型的函数a -> IO b(我正在简化).这IO意味着该函数可以执行一些i/o(在这种情况下:写入屏幕,这就是做什么print).

    mapM_ 将所有这些单独的i/o连接在一起,确保它们以正确的顺序出现.

笔记:

  • 你的原文displayAllFilms实际上没有做任何事情:输出与输入相同,任何打印到屏幕的唯一原因是你从ghci提示符运行它
  • 它是拼写的\n,不是/n(虽然我没有明确地使用它,因为print/ putStrLn自动在最后添加换行符)