在 PureScript 中专门化 class 个实例
Specialize class instance in PureScript
假设我有以下类型:
newtype T1 a = T1 a
我可以为它创建一个 Show
实例:
instance showT1Generic :: Show a => Show (T1 a) where
show (T1 a) = "generic: " <> show a
但是,假设我想为类型 T1 Int
做一些特殊的事情。我试过这样做:
instance showT1Int :: Show (T1 Int) where
show (T1 a) = "int: " <> show a
它编译了,但是 psci
中的 运行 没有按预期工作:
> T1 'a'
generic: 'a'
> T1 1
generic: 1
我做错了吗?
定义这两个实例将引发 OverlappingInstances
警告,原因是您在此处找到的 - 它可以使选择的实例不可预测。
我认为如果您翻转实例定义的顺序,这将起作用,但不建议忽略 OverlappingInstances
警告。
你不能真正做你在这里想做的事——你可以用新类型改变一个实例的行为,但是为一些具体类型专门化实例并有一个通用的回退总是会导致重叠的实例。也许如果我们引入 instance chains 这将成为可能,但在那之前你最好对这种事情使用单态函数。
假设我有以下类型:
newtype T1 a = T1 a
我可以为它创建一个 Show
实例:
instance showT1Generic :: Show a => Show (T1 a) where
show (T1 a) = "generic: " <> show a
但是,假设我想为类型 T1 Int
做一些特殊的事情。我试过这样做:
instance showT1Int :: Show (T1 Int) where
show (T1 a) = "int: " <> show a
它编译了,但是 psci
中的 运行 没有按预期工作:
> T1 'a'
generic: 'a'
> T1 1
generic: 1
我做错了吗?
定义这两个实例将引发 OverlappingInstances
警告,原因是您在此处找到的 - 它可以使选择的实例不可预测。
我认为如果您翻转实例定义的顺序,这将起作用,但不建议忽略 OverlappingInstances
警告。
你不能真正做你在这里想做的事——你可以用新类型改变一个实例的行为,但是为一些具体类型专门化实例并有一个通用的回退总是会导致重叠的实例。也许如果我们引入 instance chains 这将成为可能,但在那之前你最好对这种事情使用单态函数。