如何为另一个类型的类中的所有类型编写实例? [英] How to write an instance for all types in another type class?

查看:114
本文介绍了如何为另一个类型的类中的所有类型编写实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须定义一个类型类 Truthy ,其中包含一个方法 true ,将类型的实例转换为 Bool 值。



我的类型声明:

  class Truthy a where 
true :: a - > Bool

接下来,我必须为各种类型定义此类的实例,包括列表和数字类型。我已经完成了列表和 Int s,但是是否有办法一次执行所有数字类型?

 实例Truthy Int其中
true =(/ =)0

我曾尝试添加类型约束,但它不起作用:

  instance(Num a)=> (Truthy a)其中
true =(/ =)0 :: a

是一种做法,类似于我的想法,或者我应该为每个数字类型单独定义它?

解决方案

这可能对家庭作业没有帮助,但你实际上可以写出这样的声明。您只需启用 -XFlexibleInstances 即可。至少在GHC中,您可以通过在文件顶部添加一个附注来实现:

  { - #LANGUAGE FlexibleInstances# - } 

如果仔细观察您收到的错误消息,它会说使用-XFlexibleInstances 。



在这种特殊情况下,您还需要启用 UndecideableInstances OverlappingInstances

  { - #LANGUAGE FlexibleInstances,UndecideableInstances,OverlappingInstances# } 

您需要 FlexibleInstances ,因为标准Haskell会不允许任何形式的类型变量在头部出现多次。这是完全正确的 - 我是最常用的扩展之一(根据这个问题<您需要 UndecideableInstances ,因为您的实例声明可能会导致类型检查器永远循环。

我认为使用 UndecideableInstances 可以通过限制它在尝试减少实例时检查的深度来防止这种情况。这通常是 - 包括在这种情况下 - 很好,但理论上可以确定特定程序是否通过了类型检查实现依赖。哈马尔指出,您需要启用 OverlappingInstances ,因为在检查它们是否重叠时,实例的上下文被忽略。在这种情况下,上下文是 Num a 位。因此,用于检查它是否重叠的实例被读为实例Truthy a ... ,并与所有内容重叠。使用 OverlappingInstances 启用,您只需要一个最特定的实例即可运行。


I have to define a type class Truthy wich contains a method true converting an instance of the type class to a Bool value.

My type class declaration:

class Truthy a where
    true :: a -> Bool

Next, I have to define instances of this class for various types, including list and numeric types. I have done it for lists and Ints, but is there a way to do it for all numeric types at once?

Based on my Int declaration:

instance Truthy Int where
    true = (/=) 0

I have tried adding type class constraint, but it does not work:

instance (Num a) => (Truthy a) where
    true = (/=) 0::a

If there is a way to do this similar to what I had in mind, or should I just define it for each numeric type separately?

解决方案

This might not help for homework, but you actually can write a declaration like that. You just have to enable -XFlexibleInstances to do so. At least in GHC, you can do this by putting a pragma at the top of your file:

{-# LANGUAGE FlexibleInstances #-}

If you look closely at the error message you got, it said something like "Use -XFlexibleInstances if you want to disable this.".

In this particular case, you would also need to enable UndecideableInstances and OverlappingInstances:

 {-# LANGUAGE FlexibleInstances,  UndecideableInstances, OverlappingInstances #-}

You need FlexibleInstances because standard Haskell does not allow instances in any form where the type variable appears more than once in the head. This is completely fine--I it is one of the most common extensions used (as per this question).

You need UndecideableInstances because your instance declaration could potentially cause the type checker to loop forever. I think using UndecideableInstances prevents this by limiting how deeply it will check when trying to reduce the instance. This is usually--including in this case--fine, but could theoretically make whether a particular program passes the type checks implementation dependent. Still, it should work in your case.

As hammar pointed out, you need to enable OverlappingInstances because the "context" of the instance is ignored when checking whether they overlap. The context is the Num a bit in this case. So the instances--for checking if it overlaps--is read as instance Truthy a... and overlaps with everything. With OverlappingInstances enabled, you just need to have one instance that is the most specific for this to work.

这篇关于如何为另一个类型的类中的所有类型编写实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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