【问题标题】:How should I implement a Cayley Table in Haskell?我应该如何在 Haskell 中实现 Cayley 表?
【发布时间】:2012-03-06 09:22:11
【问题描述】:

我有兴趣推广一些计算工具以使用Cayley Table,这意味着基于查找表的乘法运算。

我可以创建一个最小的实现如下:

date CayleyTable = CayleyTable {
    ct_name :: ByteString,
    ct_products :: V.Vector (V.Vector Int)
} deriving (Read, Show)

instance Eq (CayleyTable) where
 (==) a b = ct_name a == ct_name b

data CTElement = CTElement { 
    ct_cayleytable :: CayleyTable,
    ct_index   :: !Int
}

instance Eq (CTElement) where
 (==) a b = assert (ct_cayleytable a == ct_cayleytable b) $
            ct_index a == ct_index b

instance Show (CTElement) where
   show = ("CTElement" ++) . show . ctp_index

a **** b = assert (ct_cayleytable a == ct_cayleytable b) $
           ((ct_cayleytable a) ! a) ! b

然而,这种方法存在许多问题,首先是通过ByteString 比较进行运行时类型检查,但包括无法使read 正常工作的事实。知道我应该如何正确地做到这一点吗?

我可以想象为Int 创建一系列新类型CTElement1、CTElement2 等,其中CTElement 类型类提供乘法并验证它们的类型一致性,但执行IO 时除外。

理想情况下,也可能有一些技巧可以只传递这个 ct_cayleytable 指针的一个副本,也许使用像 ?cayleytable 这样的隐式参数,但这不能很好地与多个不兼容的 Cayley 表一起使用,并且通常令人讨厌.

另外,我已经收集到向量中的索引可以被视为一个comonad。是否有任何好的comonad实例用于vector或任何可能有助于平滑这种类型检查的东西,即使最终在运行时进行?

【问题讨论】:

  • 为什么要使用字节串?尽管除非您可以仅从名称和索引中派生出 cayley 表,否则 Read 实例是不可能的。
  • 没有理由,ct_name 的存在只是为了让Eq CayleyTable 更快,因为 Cayley 表可能有数百万个条目。 Int 也可以正常工作。理想情况下,Read 应该从类型系统中学习特定的 Cayley 表,大概read "0" :: CTElementFoo 应该总是返回一个合理的值,或者如果索引基于 1,则可能使用 1。

标签: math haskell abstraction comonad


【解决方案1】:

你需要意识到 Haskell 的类型检查器只检查类型。所以你的 CaleyTable 需要是一个类。

class CaleyGroup g where
caleyTable :: g -> CaleyTable
... -- Any operations you cannot implement soley by knowing the caley table

data CayleyTable = CayleyTable {
...
} deriving (Read, Show)

如果在编译时不知道 caleyTable,则必须使用 rank-2 类型。由于编译器需要在您的代码使用它时强制执行 CaleyTable 存在的不变量。

manipWithCaleyTable :: Integral i => CaleyTable -> i -> (forall g. CaleyGroup g => g -> g) -> a

例如可以实现。它允许您在 CaleyTable 上执行组操作。它通过组合 i 和 CaleyTable 来创建一个新类型,并将其传递给它的第三个参数。

【讨论】:

  • 是的,我提到该选项为“我可以想象..”但是.. 我应该阅读 rank-2-types 因为我从来没有像这样使用过它们。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-24
  • 2015-06-03
  • 2014-06-12
  • 2011-06-07
  • 1970-01-01
相关资源
最近更新 更多