2017-09-07 20 views
1

私はHaskellでサブクラス化を使用して、クラスにインクリメンタルな特異性を適用し、運がないことを試みています。Haskellでサブクラス化を使用して増分特異性を適用するには?

私の最初の試み:サブクラスにスーパークラスの種類/メソッドを公開するためのいくつかの構文の方法があった場合、私は疑問に思い

Subclassing.hs:10:8: error: 
    ‘TheType’ is not a (visible) associated type of class ‘SubClass’ 

Subclassing.hs:15:3: error: 
    ‘theFunc’ is not a (visible) method of class ‘SubClass’ 

module Subclassing where 

class SuperClass a where 
    type TheType a :: * 
    theFunc :: TheType a -> TheType a 

class SuperClass b => SubClass b where 
    type TheType b = Int 

data MyType 

instance SubClass MyType where 
    theFunc x = x + x 

はこれをもたらしました。だから、ネットで少し調べたが、何も見つかりませんでした。

は私の第二の試みで、私は、サブクラスに制約、スーパークラスのユニバーサルインスタンスを定義することによって、問題を強制しようとした:

{-# LANGUAGE TypeFamilies   #-} 
{-# LANGUAGE AllowAmbiguousTypes #-} 
{-# LANGUAGE FlexibleInstances  #-} 
{-# LANGUAGE UndecidableInstances #-} 

module Subclassing where 

class SuperClass a where 
    type TheType a :: * 
    theFunc :: TheType a -> TheType a 

class SubClass b 
instance SubClass c => SuperClass c where 
    type TheType c = Int 

data MyType 

instance SubClass MyType 
instance SuperClass MyType where 
    theFunc x = x + x 

testFunc :: SuperClass d => [TheType d] -> TheType d 
testFunc = sum . (map theFunc) 

それは、この得られた:私は

Subclassing2.hs:25:23: error: 
    • Overlapping instances for SuperClass a0 
     arising from a use of ‘theFunc’ 
     Matching givens (or their superclasses): 
     SuperClass d 
      bound by the type signature for: 
        testFunc :: SuperClass d => [TheType d] -> TheType d 
      at Subclassing2.hs:24:1-52 
     Matching instances: 
     instance SubClass c => SuperClass c 
      -- Defined at Subclassing2.hs:15:10 
     instance SuperClass MyType -- Defined at Subclassing2.hs:21:10 
     (The choice depends on the instantiation of ‘a0’) 
    • In the first argument of ‘map’, namely ‘theFunc’ 
     In the second argument of ‘(.)’, namely ‘(map theFunc)’ 
     In the expression: sum . (map theFunc) 

を3回目の試みでは、サブクラスをクラスではなくタイプにしようとしました。 は(私はこれが原因のnewtype値コンストラクタの単一のフィールドの制限により、限られた適用性を持っているだろうことに気づいたが、アイデアの外でした。):

{-# LANGUAGE TypeFamilies   #-} 
{-# LANGUAGE AllowAmbiguousTypes #-} 

module Subclassing where 

class SuperClass a where 
    type TheType a :: * 
    theFunc :: TheType a -> TheType a 

newtype SubClass = SubClass { unSubClass :: Int -> Int } 
instance SuperClass SubClass where 
    type TheType SubClass = Int 
    theFunc = unSubClass 

testFunc :: SuperClass d => [TheType d] -> TheType d 
testFunc = sum . (map theFunc) 

そしてそれは、この得られた:

Subclassing3.hs:17:13: error: 
    • Couldn't match type ‘Int -> Int’ with ‘Int’ 
     Expected type: TheType SubClass -> TheType SubClass 
     Actual type: SubClass -> Int -> Int 
    • In the expression: unSubClass 
     In an equation for ‘theFunc’: theFunc = unSubClass 
     In the instance declaration for ‘SuperClass SubClass’ 

Subclassing3.hs:20:23: error: 
    • Couldn't match type ‘TheType a0’ with ‘TheType d’ 
     Expected type: TheType a0 -> TheType d 
     Actual type: TheType a0 -> TheType a0 
     NB: ‘TheType’ is a type function, and may not be injective 
     The type variable ‘a0’ is ambiguous 
    • In the first argument of ‘map’, namely ‘theFunc’ 
     In the second argument of ‘(.)’, namely ‘(map theFunc)’ 
     In the expression: sum . (map theFunc) 
    • Relevant bindings include 
     testFunc :: [TheType d] -> TheType d 
      (bound at Subclassing3.hs:20:1) 
+2

私はあなたがクラスが何であるかを非常にgrokkedしていないと思います。ハスケル型クラスは、典型的なオブジェクト指向言語のクラスとは非常に異なっています。クラスの_インスタンス_を定義する(具体的な型に対しては、3回目の試行でnewtypeとして行うことができます)、基本的にそれのサブクラスを定義することとは異なります。 – leftaroundabout

+3

おそらく[XY](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)の質問に答えるには、このすべてが欲しい特に、TheTypeファミリーは意味を持たないようです。なぜあなたはそれに関連するタイプの家族が必要だと思いますか? – leftaroundabout

+1

これは間違いなくハスケルがサポートするために作られたものではありません。つまり、私はこれまでに[概念の要点の証明](https://gist.github.com/harpocrates/38ec83098cd45d7e8bccbb2d7001acb5#file-subtype-hs)を作成しました。それがあなたが探しているものなら、疑問はおそらくhttps://stackoverflow.com/q/41504364/3072788の複製です。 – Alec

答えて

0

あなたの最初の推測は私には分かりやすいようですが、いいえ、Haskellは関連する型やメソッドを(サブ)クラス定義で定義させません。