如何在Haskell的子类定义中定义默认实现? [英] How to define default implementation in subclass definition in Haskell?

查看:122
本文介绍了如何在Haskell的子类定义中定义默认实现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Haskell的新成员,以下是我的问题:给出这个类的



  class MyClass a where 
foo :: a - > [a]

然后我有一个更具体的子类:

  class(MyClass a)=> SubClass a where 
foo param = [bar param]
bar :: a - > a

但它无法按预期工作。我期待在 SubClass 的定义中设置一个默认实现,但它不会。我将需要单独为 MyClass 定义实例,但这听起来很愚蠢。当我知道某个子类完全满足某些属性时,我该如何实现默认实现?

更具体地说,我想在Haskell中表示类满足一些属性,其父类的一些函数可以具有默认实现。在我的例子中, SubClass 有属性 bar ,这样我知道 foo 肯定是以这种方式定义的。



这个问题的更一般形式是,使用类和实例重用是个好主意吗?



我发现这篇文章:在Haskell中包含使用默认实现的类型类型



它非常接近,但仍然没有完全回答我的问题,它们的形式有点不同。

解决方案

在Daniel的答案中详细阐述:

假设你有一个新的数据类型 MyData ,定义为

  data MyData = D1 | D2 

您想让 MyData 一个实例 SubClass 。您首先尝试显而易见的解决方案。

  instance SubClass MyData其中
bar x = case x of {D1 - > D2; D2 - > D1}

然而,对类型签名的快速检查表明,这不起作用,因为在它可以是 SubClass 的实例之前,类型必须是 MyClass 的实例。因此,您可以使 MyData MyClass 的一个实例。

  instance MyClass MyData 

同样,这会产生一个错误, code> foo 包含在 MyClass 的最小完整定义中。为了您的实例能够工作,您必须手动定义 foo ,从而破坏默认声明的目的。



简而言之,在基本的Haskell98(或者Haskell2010)中没有办法做到这一点。然而,幸运的是,GHC提供了一个有用的扩展,名为 DefaultSignatures 。所以,使用Daniel的例子:

  { - #LANGUAGE DefaultSignatures# - } 

class MyClass a where
foo :: a - > [a]
default foo :: SubClass a => a - > [a]
foo param = [param]

class MyClass a => SubClass a where
bar :: a - > a

现在,您可以定义这些实例,并且它们将按照您的预期工作。该解决方案的缺点是必须在 MyClass 中定义默认定义,但这是必需的。 foo 的定义属于 MyClass (或它的一个实例声明)的定义,所以如果你能在 SubClass ,Haskell的类型隔离定义中定义默认声明 foo 被打破。

I am new comer of Haskell and following is my question:

given this class:

class MyClass a where
    foo :: a -> [a]

then I have a subclass that is more specific:

class (MyClass a) => SubClass a where
    foo param = [bar param]
    bar :: a -> a

but it doesn't work as expected. I was expecting a default implementation is setup in the definition of SubClass but it doesn't. I will need to define the instance for MyClass seperately, but that sounds stupid. How can I achieve default implementation when I know some subclass satisfies some property definitely?

More specifically, I want to express in Haskell, that when a class satisfies some properties, some functions for its parent can have default implementation. In my example, SubClass has property bar such that I know foo is definitely defined in such a way.

A more general form of this question is, is it a good idea to reuse by using classes and instances?

I found this post: Inclusion of typeclasses with default implementation in Haskell

It's quite close, but still not answering my question totally and their forms are little bit different.

解决方案

Elaborating on Daniel's answer:

Suppose you have a new datatype MyData, defined as

data MyData = D1 | D2

You want to make MyData an instance of SubClass. You try the obvious solution first.

instance SubClass MyData where
    bar x = case x of { D1 -> D2 ; D2 -> D1 }

A quick examination of the type signatures, though, reveals that this won't work, because a type has to be an instance of MyClass before it can be an instance of SubClass. So you make MyData an instance of MyClass.

instance MyClass MyData

Again, this raises an error, because foo is included in the minimal complete definition of MyClass. For your instance to work, you would have to manually define foo, thus defeating the purpose of the default declaration.

In short, there is no way to do this in basic Haskell98 (or Haskell2010, for that matter). Thankfully, however, GHC provides a useful extension called DefaultSignatures. So, using Daniel's example:

{-# LANGUAGE DefaultSignatures #-}

class MyClass a where
    foo :: a -> [a]
    default foo :: SubClass a => a -> [a]
    foo param = [param]

class MyClass a => SubClass a where
    bar :: a -> a

And now, you can define the instances and they will work as you would expect. The downside to this solution is that the default definition has to be defined in MyClass, but this is necessary. The definition of foo belongs to the definition of MyClass (or one of its instance declarations), so if you were able to define the default declaration of foo within the definition of SubClass, Haskell's type isolation would be broken.

这篇关于如何在Haskell的子类定义中定义默认实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆