假设我有
class C1 t
和
class C2 t
这里请注意:
C1 :: * -> Constraint
C2 :: * -> Constraint
我可以做
class (C1 t, C2 t) => C3 t
instance (C1 t, C2 t) => C3 t
所以我们有
C3 :: * -> Constraint
请注意,C3 t
仅当 C1 t
和 C2 t
有效时才有效。
此外,如果我们添加一堆扩展:
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE UndecidableSuperClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeOperators #-}
我们甚至可以做一些更通用的事情,如下所示:
class (c1 a, c2 a) => And c1 c2 a
instance (c1 a, c2 a) => And c1 c2 a
type C3 = C1 `And` C2
这按预期工作。
这不是我希望能够执行的唯一约束组合,例如,我希望能够组合两个变量的约束,例如 And2
:
class (c1 a b, c2 a b) => And2 c1 c2 a b
instance (c1 a b, c2 a b) => And2 c1 c2 a b
或者向第一个变量添加额外的约束:
class (c1 a, c2 a b) => AddFirst c1 c2 a b
instance (c1 a, c2 a b) => AddFirst c1 c2 a b
当然有很多可能性。
现在不想重新发明轮子,我正在查看 constraints包,我从中引用:
ConstraintKinds made type classes into types of a new kind, Constraint.
Eq :: * -> Constraint
Ord :: * -> Constraint
Monad :: (* -> *) -> Constraint
With ConstraintKinds we can put into code a lot of tools for manipulating these new types without such awkward workarounds.
这似乎符合要求,但我有点迷失在文档中。
constraints
包是否能实现我在本文中所述的功能?如果是这样,您能举个例子吗?如果没有,是否有其他用于约束操作的包,或者我应该自己将其填写到库中?
最佳答案
在 generics-sop ,这种约束操作是经常需要的,因为它的相当多的函数是通过约束参数化的。
因此,该库包含一个模块 Generics.SOP.Constraint
与许多这样的帮助器类,特别是你的 And
。如果事实证明它们普遍有用,原则上可以添加更多内容。
(&&&)
。同样,generics-sop 也具有类似的功能(尽管它的功能要少得多,并且旨在做得更少),在 Generics.SOP.Dict
中。 .
关于haskell - 约束操作包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42549277/