Haskell 我可以从具有关联类型族的类的实例中删除类型实例化吗?

Haskell 我可以从具有关联类型族的类的实例中删除类型实例化吗?,haskell,types,type-families,Haskell,Types,Type Families,我有以下代码: {-# 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 -&g

我有以下代码:

{-# 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
-除非我特别想偏离这个模式

我计划使用的大多数实例都应该是默认的,带有
ta~[a]
,但有些实例确实需要它们的 拥有
T
类型。我不愿意容忍大量相同的琐碎定义,比如给定的
一可以做什么?

您只需添加一个默认类型实例化:

{-# 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


您只需添加一个默认类型实例化:

{-# 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


在不可能的情况下,这不是一个最小化的例子:因为在类中的任何地方,只要你不提到“代码> A <代码> >(只有<代码> T A<代码>),请考虑<代码> C类A,其中PRD::A---BOOL < /代码>;它不需要花哨的扩展,功能也同样强大(多亏了关联类型上的
r->a
注释)。@DanielWagner即使它被严重地最小化了,我还是可以使用你的建议。你看,我的类中有两种方法:“连接”,它们的签名中都有
a
ta
,还有“隔离”,它们只有
ta
,但从来没有
a
。(例如,
pred
将被隔离。)现在,我可以将所有隔离的方法放在一个类
C
中,然后将连接方法放在一个双参数子类
C ta=>B a ta
中。在不太可能的情况下,这不是一个最小化的示例:因为在类中的任何地方都没有单独提到
a
(只有<代码> T A<代码>),考虑<代码> > C类A,其中PRD::A---BOOL ;它不需要花式扩展,而且也不太强大(得益于<代码> R-> A/<代码>注释您的关联类型).DayielWaGNER,即使它被最小化了,我也可以实际使用您的建议。“连接”,即在签名中同时包含
a
ta
,以及“隔离”,即仅包含
ta
,但从不包含
a
(例如
pred
将被隔离。)现在,我可以将所有隔离的方法放入一个类
C
,然后将连接方法放入一个双参数子类
cta=>bata