Rey*_*och 10 haskell default multiparameter typeclass
例如,我有一个类型类:
class MyClass a b c where
fun01 :: a -> b
fun02 :: a -> c
fun03 :: a -> b -> c -> ()
fun04 :: a -> WhatEver
Run Code Online (Sandbox Code Playgroud)
我想为我提供一个默认实现,让我们调用它BaseDataType来定义fun03自我和fun01和的实现fun02.然后我会有这样的事情:
class MyClass BaseDataType b c where
fun03 = fun01 <$> fun02 ...
fun04 = fun02 ...
Run Code Online (Sandbox Code Playgroud)
而不是完成我的类实例并避免所有的样板代码fun03,fun04我只是提供fun01并fun02喜欢这样:
instance MyClass BaseDataType Int Char where
fun01 = 1
fun02 = 'C'
Run Code Online (Sandbox Code Playgroud)
是否可能有一些语言扩展允许这种行为?我在这个主题上找不到任何东西.
use*_*038 11
没有这样的扩展,但只需将您的类拆分为两个类就可以实现此功能:
class MyClass1 a b c where
fun03 :: a -> b -> c -> ()
fun04 :: a -> WhatEver
class MyClass1 a b c => MyClass2 a b c where
fun01 :: a -> b
fun02 :: a -> c
Run Code Online (Sandbox Code Playgroud)
然后您的实例将按您希望的方式工作:
-- NB: need the MyClass2 constraint if you use `fun01` or `fun02` in the definitions
-- This requires UndecidableInstances
instance MyClass2 BaseDataType b c => MyClass1 BaseDataType b c where
fun03 = fun01 <$> fun02 ...
fun04 = fun02 ...
instance MyClass2 BaseDataType Int Char where
fun01 = 1
fun02 = 'C'
Run Code Online (Sandbox Code Playgroud)
班级用户不受影响; 他们可以继续消费以前使用的MyClass2地方MyClass并获得完全相同的功能.
旁白:原来的定义MyClass,并MyClass1和MyClass2甚至不编译由于一些不明确的类型错误(c在类型没有被提及fun01,等) -我认为这个类的定义只是为了演示的目的,我还没有试过解决这个问题.
您可以像这样使用DefaultSignatures
class MyClass a b c where
fun01 :: a -> b
fun02 :: a -> c
fun03 :: a -> b -> c -> ()
default fun03 :: (a ~ BaseDataType) => a -> b -> c -> ()
fun03 = fun01 <$> fun02 ...
fun04 :: a -> WhatEver
default fun04 :: (a ~ BaseDataType) => a -> WhatEver
fun04 = fun02 ...
Run Code Online (Sandbox Code Playgroud)