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
。