“Разделение на подклассы” шоу в Haskell?

Позволяет говорят, что у меня есть следующее:

data Greek = Alpha | Beta | Gamma | Phi deriving Show

Я хочу использовать показ по умолчанию всех объектов кроме Беты, которую я хочу сказать "два".

Я могу сделать это?

6
задан Don Stewart 18 April 2011 в 23:35
поделиться

4 ответа

Насколько я знаю, вы не можете. Механизм извлечения в любом случае не поддерживает изменение или расширение производных экземпляров.

3
ответ дан 8 December 2019 в 03:00
поделиться

Некоторые другие предложения отлично работают в вашем конкретном примере, и я бы посоветовал использовать их.

Но в более общем случае вы можете использовать обобщенное программирование типов данных .

Используя универсальное программирование, вы можете писать функции, которые работают с несколькими типами данных, то есть функции, которые делают то же самое для каждого типа данных. Примеры таких функций: 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 (она добавляет дополнительный набор круглых скобок). Но это может быть хорошей отправной точкой для написания ваших собственных универсальных функций.

4
ответ дан 8 December 2019 в 03:00
поделиться

Не то чтобы это полностью удовлетворительно, но вы могли бы сделать:

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.

7
ответ дан 8 December 2019 в 03:00
поделиться

создание Show использует стандартный механизм создания экземпляров (просто возвращает определение). Если вам нужны какие-то особые вещи, вам придется создать его вручную:

data Greek = Alpha | Beta | Gamma | Phi

instance Show Greek
    where
        show Alpha = "Alpha"
        show Beta  = "2"
        show Gamma = "Gamma"
        show Phi   = "Phi"
17
ответ дан 8 December 2019 в 03:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: