Позволяет говорят, что у меня есть следующее:
data Greek = Alpha | Beta | Gamma | Phi deriving Show
Я хочу использовать показ по умолчанию всех объектов кроме Беты, которую я хочу сказать "два".
Я могу сделать это?
Насколько я знаю, вы не можете. Механизм извлечения в любом случае не поддерживает изменение или расширение производных экземпляров.
Некоторые другие предложения отлично работают в вашем конкретном примере, и я бы посоветовал использовать их.
Но в более общем случае вы можете использовать обобщенное программирование типов данных .
Используя универсальное программирование, вы можете писать функции, которые работают с несколькими типами данных, то есть функции, которые делают то же самое для каждого типа данных. Примеры таких функций: show
и ==
(по этой причине они могут быть получены в GHC).
Это пример использования обычной библиотеки:
{-# LANGUAGE TemplateHaskell, EmptyDataDecls, TypeFamilies #-}
import Generics.Regular
import qualified Generics.Regular.Functions.Show as G
data Greek = Alpha | Beta | Gamma | Phi
-- These two lines are all that is needed to use
-- Regulars generic functions on the 'Greek' data type.
$(deriveAll ''Greek "PFGreek")
type instance PF Greek = PFGreek
-- Manual written instance for 'Show'
instance Show Greek where
show Beta = "Two"
show x = G.show x -- Use Regulars 'show' for the boring parts
Честно говоря, мне не очень нравится вывод функции Regulars show
(она добавляет дополнительный набор круглых скобок). Но это может быть хорошей отправной точкой для написания ваших собственных универсальных функций.
Не то чтобы это полностью удовлетворительно, но вы могли бы сделать:
data Greek = Alpha | Beta | Gamma | Phi
deriving (Show)
showGreek Beta = "2"
showGreek x = show x
И использовать showGreek вместо show. Если вам нужен настоящий экземпляр шоу (в моем коде я считаю, что он мне нужен меньше, чем думают новички), вы могли бы сделать довольно громоздкий:
newtype Greek' = Greek' Greek
instance Show Greek' where
show (Greek' g) = showGreek g
Если бы это был мой код, я бы просто придерживался showGreek
.
Я использую хорошее практическое правило: экземпляры Show и Read генерируются только Haskell. Если show не создает действительный код Haskell, его не должно быть в экземпляре Show.
создание Show
использует стандартный механизм создания экземпляров (просто возвращает определение). Если вам нужны какие-то особые вещи, вам придется создать его вручную:
data Greek = Alpha | Beta | Gamma | Phi
instance Show Greek
where
show Alpha = "Alpha"
show Beta = "2"
show Gamma = "Gamma"
show Phi = "Phi"