如何隐藏数据中的名称和年龄人a =人{name :: a,age :: Int}派生出在haskell中显示

时间:2013-04-10 18:36:36

标签: haskell

假设我们有

data People a = Person { name::a , age::Int} deriving Show 
当我输入

时,在Hugs中

> Person "Alihuseyn" 20

我得Person {name = "Alihuseyn", age = 20} 但我想得到Person Person "Alihuseyn" 20

我的意思是如何在不更改数据的情况下隐藏名称和年龄的提及?

2 个答案:

答案 0 :(得分:11)

如果您愿意,可以随时为所有类型提供自定义Show实例:

data People a = Person { name::a , age::Int} 

instance (Show a) => Show (People a) where
    show (Person name age) == "Person " ++ show name ++ " " ++ show age

或者不那么优雅,编写自定义访问器:

data People a = Person a Int deriving Show
name (Person n _) = n
age (Person _ a) = a

无论哪种方式,您都必须更改People的声明,否则您将无法使用派生的Show实例。

作为旁注,如果您的数据类型只包含一个构造函数,那么通常会在类型后面命名构造函数,因此它将是data Person a = Person { name :: a, age :: Int }

答案 1 :(得分:7)

这使用GHC.Generics提供showsPrecDefault,可以很容易地用来定义Show个实例。

data Person a = Person { name :: a, age :: Int } deriving Generic

instance Show a => Show (Person a) where showsPrec = showsPrecDefault

>>> Person "Alihuseyn" 20
Person "Alihuseyn" 20

showsPrecDefault的定义如下。

{-# LANGUAGE
    DeriveGeneric
  , FlexibleContexts
  , FlexibleInstances
  , KindSignatures
  , TypeOperators
  , TypeSynonymInstances #-}
import GHC.Generics

class GShow f where
  gshowsPrec :: Int -> f a -> ShowS

instance GShow U1 where
  gshowsPrec _ U1 = id

instance Show c => GShow (Rec0 c) where
  gshowsPrec p = showsPrec p . unK1

instance GShow f => GShow (D1 d f) where
  gshowsPrec p = gshowsPrec p . unM1

instance Constructor c => GShow (C1 c U1) where
  gshowsPrec _ c@(M1 U1) = showParen (isInfix c) (showString (conName c))

instance (Constructor c, GShow (M1 i c f)) => GShow (C1 c (M1 i c f)) where
  gshowsPrec = gshowsPrec'

instance (Constructor c, GShow (f :+: g)) => GShow (C1 c (f :+: g)) where
  gshowsPrec = gshowsPrec'

instance (Constructor c, GShow (f :*: g)) => GShow (C1 c (f :*: g)) where
  gshowsPrec = gshowsPrec'

gshowsPrec' :: (Constructor c, GShow f) => Int -> C1 c f p -> ShowS
gshowsPrec' p c@(M1 f) =
  showParen (p > 10) $
  showParen (isInfix c) (showString (conName c)) .
  showChar ' ' .
  gshowsPrec 11 f

isInfix :: Constructor c => t c (f :: * -> *) a -> Bool
isInfix c = case conFixity c of
  Infix _ _ -> True
  _ -> False

instance GShow f => GShow (S1 s f) where
  gshowsPrec p = gshowsPrec p . unM1

instance (GShow a, GShow b) => GShow (a :+: b) where
  gshowsPrec p (L1 a) = gshowsPrec p a
  gshowsPrec p (R1 b) = gshowsPrec p b

instance (GShow a, GShow b) => GShow (a :*: b) where
  gshowsPrec p (a :*: b) =
    gshowsPrec (p + 1) a .
    showChar ' ' .
    gshowsPrec (p + 1) b

showsPrecDefault :: (Generic a, GShow (Rep a)) => Int -> a -> ShowS
showsPrecDefault p = gshowsPrec p . from