使一个类型类实例自动成为另一个类型类实例

2023-12-02

我想要实现的是以下类的任何实例(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.

  1. 这不是Show类是有的。Show用于简单地显示纯数据,以一种实际上是 Haskell 代码的方式,并且可以再次使用,产生原始值。
  2. SampleSpace也许一开始就不应该是一个类。它似乎基本上是具有类似内容的类型类Map a Rational与他们有关。为什么不直接将其用作普通字段data type?
  3. 即使我们接受这个设计……如此通用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(使用前将#替换为@)

使一个类型类实例自动成为另一个类型类实例 的相关文章

  • 在 ghci 下执行 `(read "[Red]") :: [Color]` 时会发生什么?

    我正在阅读以下小节现实世界 Haskell 第 6 章 类型类 http book realworldhaskell org read using typeclasses html关于一个实例Read for Color 它实现了reads
  • cabal install wx 缺少 C 库

    Env 操作系统 feodra 16 Haskell 平台 wxGTK 开发 GHHC 7 0 4 我正在尝试安装 wxHaskell 阴谋集团安装wx 然后给出这些错误 缺少对外国库的依赖 缺少 C 库 wx baseu 2 8 wx b
  • 管道 - 将多个来源/生产者合并为一个

    我正在使用读取文件sourceFile 但我还需要在处理操作中引入随机性 我认为最好的方法是拥有一个这样的制片人 Producer m StdGen ByteString 其中 StdGen 用于生成随机数 我打算让生产者执行 source
  • 如何从具有函数依赖关系的类型类中获取和使用依赖类型?

    如何从具有函数依赖关系的类型类中获取和使用依赖类型 为了澄清并给出我最近的尝试的一个例子 从我正在编写的实际代码中最小化 class Identifiable a b a gt b where if you know a you know
  • 使用 Parsec 解析正则表达式

    我正在尝试通过实现一个小型正则表达式解析器来学习秒差距 在 BNF 中 我的语法类似于 EXP EXP LIT EXP LIT 我尝试在 Haskell 中实现这一点 expr try star lt gt try litE lt gt l
  • 并行 Haskell - GHC GC 火花

    我有一个正在尝试并行化的程序 带有可运行代码的完整粘贴here http lpaste net 101528 我进行了分析 发现大部分时间都花在findNearest这本质上是一个简单的foldr超过一个大Data Map findNear
  • 与 Functor 不同,Monad 可以改变形状?

    我一直很喜欢以下关于单子相对于函子的力量的直观解释 单子可以改变形状 函子不能 例如 length fmap f 1 2 3 总是等于3 然而 对于单子来说 length 1 2 3 gt gt g往往不等于3 例如 如果g定义为 g Nu
  • 使用默认值压缩而不是删除值?

    我正在 haskell 中寻找一个函数来压缩两个长度可能不同的列表 我能找到的所有 zip 函数都只是删除列表中比其他列表长的所有值 例如 在我的练习中 我有两个示例列表 如果第一个比第二个短 我必须用 0 填充 否则我必须使用 1 我不允
  • 类型类实例化中的现有常量(例如构造函数)

    考虑这个伊莎贝尔代码 theory Scratch imports Main begin datatype Expr Const nat Plus Expr Expr 实例化是相当合理的plus输入 class 以获得良好的语法Plus构造
  • 来自数据类型的 Haskell 随机数

    我对 Haskell 还很陌生 我有一个数据类型 data Sentence Prop Int No Sentence And Sentence Or Sentence deriving Eq 我已经为它写了一个 Show 实例 然而 无论
  • Haskell 中的内部爆炸模式是否总是强制使用外部构造函数?

    在 Haskell 中 是否存在对于数据类型 LANGUAGE BangPatterns import Control DeepSeq data D D Int 实例 instance NFData D where rnf D 与具有另一个
  • Haskell 中的“修复”是什么?为什么“修复错误”会打印无限字符串?为什么“拿 10 美元修复错误”也有同样的作用?

    长话短说 我在看西蒙 佩顿 琼斯的演讲 https www youtube com watch v re96UgMk6GQ 并且当时21 41 https youtu be re96UgMk6GQ t 1301他引用了一句话 我正在解决一个
  • 在 Haskell 中调试时打印时间戳

    我仍在学习 Haskell 并调试一些函数 并且通常有一个时间戳函数来了解某些操作何时开始和停止 doSomeAction String gt IO doSomeAction arg1 do putStrLn lt lt makeTime
  • 承诺的反面是什么?

    承诺代表将来可能可用 或无法实现 的值 我正在寻找的是一种数据类型 它表示将来可能变得不可用的可用值 可能是由于错误 Promise a b TransitionFromTo
  • Haskell 五个独特的 Wordle 单词

    为了好玩 我正在尝试解决 Matt Parker 在他的 Haskell 频道 Standup Maths in Haskell 频道的链接视频中谈到的与 Wordle 相关的问题 基本上 找到 5 个没有任何共同字母的 5 个字母单词 因
  • Haskell 有 takeUntil 函数吗?

    目前我正在使用 takeWhile x gt x 1 x 89 l 从列表中获取最多为 1 或 89 的元素 但是 结果不包括这些标记值 Haskell 是否有一个标准函数可以提供这种变化takeWhile结果中包含哨兵 到目前为止 我对胡
  • 如何获得具有超载字段名称的经典镜头?

    我正在尝试为具有相同字段名称的记录构建镜头 除此之外 我试图 包装 扩展 这些基本记录 并希望相同的字段名称适用于包装 扩展的记录 我相信 优雅的镜头就是这样做的 我如何让以下内容发挥作用 Data types for context of
  • 如何给Servant中的所有端点添加前缀?

    我在 Haskell 仆人中有一个 hello world 应用程序 这是其中的一部分 type API my items gt Get JSON MyItem lt gt my items gt Capture id Int gt Get
  • 运行程序的最佳 Haskell 库是什么? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 如果我要将一个程序投入生产 我需要该程序做几件事才能将其视为 可操作 也就是说 工程师和操作人员以可测量
  • 为自定义镜头编写类别实例

    我一直在读这个article http www haskellforall com 2012 01 haskell for mainstream programmers 28 html用于理解镜头 我知道这不同于 爱德华 克内特 Edwar

随机推荐