当我们创建一个类型类时,我们通常假设它的函数必须服从某些属性.因此,我们对其各自的类型类别有Monoid和Monad定律.但是,如果有一些法律,比如关联性,我想指出多个类可能会也可能不会遵守该法则呢?在Haskell的类型系统中有没有办法做到这一点?这种类型类的类型类在实践中是否可行?
这是代数的一个激励性例子:
class Addition x where
add :: x -> x -> x
class Multiplication x where
mult :: x -> x -> x
instance Addition Int where
add = (+)
instance Multiplication Int where
add = (*)
Run Code Online (Sandbox Code Playgroud)
现在,如果我想指定Int上的添加是关联和可交换的,我可以创建类和实例:
class (Addition x) => AssociativeAddition x where
class (Addition x) => CommutativeAddition x where
instance AssociativeAddition Int where
instance CommutativeAddition Int where
Run Code Online (Sandbox Code Playgroud)
但这很麻烦,因为我必须为所有类创建所有可能的组合.我不能只创建关联类和交换类,因为如果加法是可交换的,但乘法不是(就像在矩阵中一样)?
我希望能做的是说:
class Associative x where
instance (Associative Addition, Commutative Addition) => Addition Int where
add = (+)
instance (Commutative Multiplication) => Multiplication Int where
mult = (*)
Run Code Online (Sandbox Code Playgroud)
可以这样做吗?
(Haskell的抽象代数包,如代数和建设性代数,目前不这样做,所以我猜不是.但为什么不呢?)
Pth*_*ame 10
您实际上可以使用最近的一些GHC扩展来执行此操作:
{-# LANGUAGE ConstraintKinds, KindSignatures, MultiParamTypeClasses #-}
import GHC.Exts (Constraint)
class Addition (a :: *) where
plus :: a -> a -> a
instance Addition Integer where
plus = (+)
class (c a) => Commutative (a :: *) (c :: * -> Constraint) where
op :: a -> a -> a
instance Commutative Integer Addition where
op = plus
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
299 次 |
| 最近记录: |