Могу ли я удалить экземпляр типа из экземпляра класса со связанным семейством типов? - PullRequest
0 голосов
/ 04 мая 2018

У меня есть этот код:

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeFamilyDependencies #-}
{-# LANGUAGE DefaultSignatures #-}

module Study where

class C a where
    type T a = r | r -> a
    pred :: T a -> Bool

    default pred :: T a ~ [a] => T a -> Bool
    pred = not . null

instance C Integer where
    type T Integer = [Integer]

Работает так:

λ Study.pred [1,2,3]
True
λ Study.pred ([ ] :: [Integer])
False

Я хотел бы сократить минимальные определения экземпляров просто до:

instance C Integer

- Если я не хочу специально отклоняться от схемы.

Большинство экземпляров, которые я планирую иметь, должны быть по умолчанию, с T a ~ [a], но некоторые действительно нуждаются в их собственный T тип. Я не хочу терпеть многочисленные идентичные тривиальные определения, подобные приведенному один. Что можно сделать?

1 Ответ

0 голосов
/ 04 мая 2018

Вы можете просто добавить экземпляр типа по умолчанию:

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeFamilyDependencies #-}
{-# LANGUAGE DefaultSignatures #-}

module Study where

data One a = One a

class C a where
    type T a = r | r -> a
    -- This looks a bit strange,
    -- because it looks like T is defined twice
    -- but that's not actually the case
    type T a = [a]
    pred :: T a -> Bool

    default pred :: T a ~ [a] => T a -> Bool
    pred = not . null

instance C Integer

instance C Char where
  type T Char = One Char
  pred = const True

*Study> :t undefined :: T Integer
undefined :: T Integer :: [Integer]
*Study> :t undefined :: T Char
undefined :: T Char :: One Char
...