Haskell派生Show为自定义类型

时间:2012-11-19 22:42:40

标签: haskell instance show

如何判断haskell在代数类型的变量列表中调用show时,应在每行之后插入“\ n”?

type Customer = (Int, Int, [Int])

我试着这样做:

instance of Show Customer where
show x = x ++ "\n"

但显然我只能为“数据......”创建这样的实例。我该如何解决这个问题?

我需要仅为了一个客户列表派生Show,这样当我显示它时,输出很容易阅读,每行一个客户。

2 个答案:

答案 0 :(得分:10)

要仅显示在不同的行上,请不要更改show,只需执行unlines (map show customerList)。这将显示它们中的每一个,然后将它们放回到中间的换行符。


但是,您询问有关更改type同义词的节目,因此以下是您的选择:

show用于数据的基本序列化。如果你想做一些不同的事情,你有几个选择:

  1. 编写一个在此实例中执行此操作的函数。
  2. 制作自己的展示类,并在display函数中定义您的展示方式。
  3. 使用newtype打包数据。
  4. 声明您自己的客户类型。
  5. 稍后添加换行符

    输入Customer =(Int,Int,[Int])

  6. 示例1

    displayC :: Customer -> String
    displayC = (++"\n").show
    

    示例2

    {-# LANGUAGE TypeSynonymInstances,  FlexibleInstances #-}
    class Display a where
      display :: a -> String
    
    instance Display Customer where
       display x = show x ++ "\n"
    

    (请注意,您应该说instance Display Customer而不是instance of Display Customer。)

    示例输出:

    *Main> display ((3,4,[5,6])::Customer)
    "(3,4,[5,6])\n"
    

    但是,应谨慎使用这些语言扩展名。

    示例3

    newtype Cust = Cust Customer
    displayCust (Cust c) = show c ++ "\n"
    

    示例4

    data CustomerTup = CTup Int Int [Int]
    displayCTup (CTup a b cs) = show (a,b,cs) ++ "\n"
    

    甚至更好,

    data CustomerRec = CRec {custno::Int, custAge::Int, custMeasurements::[Int]}
      deriving Show
    displayCRec r = show (custno r,custAge r,custMeasurements r) ++ "\n"
    

    你甚至可以坚持Show实例的做事方式。 data方式很好,因为类型安全性更高,记录类型可以阻止你犯错误的位置错误。

    示例5

    stuff = unlines $ map show  [(1,2,[3,4]),(5,6,[7,8,9])]
    

    甚至

    morestuff = unlines [show (1,2,[3,4]), 
                         show (5,6,[7,8,9]),
                         "are all more numbery than",
                         show (True,4,False)]
    

答案 1 :(得分:3)

AndrewC的一个很好的补充:

6。编写一个函数,为类Show中任何类型的文本表示添加一个新行:

display :: Show a => a -> String
display = flip shows "\n"

例如:

> display (2, 3, [5, 7, 11])
"(2,3,[5,7,11])\n"