How to write an instance for all types in another type class?

前端 未结 1 1994
眼角桃花
眼角桃花 2021-02-05 21:53

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

My type

相关标签:
1条回答
  • 2021-02-05 22:36

    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 UndecidableInstances and OverlappingInstances:

     {-# LANGUAGE FlexibleInstances,  UndecidableInstances, 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 UndecidableInstances because your instance declaration could potentially cause the type checker to loop forever. I think using UndecidableInstances 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.

    0 讨论(0)
提交回复
热议问题