我想要实现的是以下类的任何实例(SampleSpace
)应该自动成为一个实例Show
, 因为SampleSpace
包含创建字符串表示所需的整个接口,因此该类的所有可能实例实际上都是相同的。
{-# LANGUAGE FlexibleInstances #-}
import Data.Ratio (Rational)
class SampleSpace space where
events :: Ord a => space a -> [a]
member :: Ord a => a -> space a -> Bool
probability :: Ord a => a -> space a -> Rational
instance (Ord a, Show a, SampleSpace s) => Show (s a) where
show s = showLines $ events s
where
showLines [] = ""
showLines (e:es) = show e ++ ": " ++ (show $ probability e s)
++ "\n" ++ showLines es
因为,正如我已经发现的,在匹配实例声明时,GHC 只查看头部,而不查看约束,因此它认为Show (s a)
也与 Rational 相关:
[1 of 1] Compiling Helpers.Probability ( Helpers/Probability.hs, interpreted )
Helpers/Probability.hs:21:49:
Overlapping instances for Show Rational
arising from a use of ‘show’
Matching instances:
instance (Integral a, Show a) => Show (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
instance (Ord a, Show a, SampleSpace s) => Show (s a)
-- Defined at Helpers/Probability.hs:17:10
In the expression: show
In the first argument of ‘(++)’, namely ‘(show $ probability e s)’
In the second argument of ‘(++)’, namely
‘(show $ probability e s) ++ "" ++ showLines es
问题:是否有可能(除了启用重叠实例之外)使类型类的任何实例自动成为另一个类型类的实例?
tl;dr:不要这样做,或者,如果你坚持的话,使用-XOverlappingInstances
.
- 这不是
Show
类是有的。Show
用于简单地显示纯数据,以一种实际上是 Haskell 代码的方式,并且可以再次使用,产生原始值。
-
SampleSpace
也许一开始就不应该是一个类。它似乎基本上是具有类似内容的类型类Map a Rational
与他们有关。为什么不直接将其用作普通字段data
type?
- 即使我们接受这个设计……如此通用
Show
当有人为具体类型创建另一个实例时,实例(或者实际上是任何单参数类的通用实例)会遇到问题 - 在以下情况下Show
,当然已经有很多实例了。那么编译器应该如何决定使用这两个实例中的哪一个呢?事实上,GHC 可以做到:如果你打开-XOverlappingInstances
扩展名,它将选择更具体的扩展名(即instance SampleSpace s => Show (s a)
被任何更具体的实例“覆盖”),但实际上这并不像看起来那么微不足道 - 如果有人定义了怎么办another这样的通用实例?重要的是要记住:Haskell 类型类始终开放,即基本上编译器必须假设all类型可能属于任何类。仅当调用特定实例时,它才真正需要证明,但它永远无法证明类型isn't在某堂课上。
我会推荐什么——从那时起Show
实例不仅仅显示数据,它应该成为不同的功能。任何一个
showDistribution :: (SampleSpace s, Show a, Ord a) => s a -> String
或者确实
showDistribution :: (Show a, Ord a) => SampleSpace a -> String
where SampleSpace
是单个具体类型,而不是类。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)