2017-09-19 11 views
0

型クラスData.Foldableは、次のように定義されますfoldrが異なる型の引数をとるData.Foldableのインスタンスを定義することは可能ですか?

class Foldable t where 
    {-# MINIMAL foldMap | foldr #-} 
    foldMap :: Monoid m => (a -> m) -> t a -> m 
    foldr :: (a -> b -> b) -> b -> t a -> b 
    .... 
    <more definitions> 

最小限のスタンザは、私はそれだけでfoldr機能でインスタンスを定義することが可能だと言います。 私がコンパイルできるすべての例では、foldr関数の型はa -> a -> aです。しかし、 は、foldr関数が実際にタイプa -> b -> bであり、タイプがaと の場合に定義することができません。

次のコードは、例を示し、それはコンパイルされません:

import Data.Foldable 

data Tree a = Tree a a | Leaf a 

class Size a where 
    size :: a -> Int 

instance Size a => Foldable (Tree a) where 
    foldr :: a -> Int -> Int 
    foldr x n = size x + n 

は、それがタイプabが本当に異なっているfoldr、と折り畳み式のインスタンスを定義することは可能ですか?

答えて

5

タイプが異なるという問題ではありません。あなたのfoldrのタイプは、Foldableに必要なものと同じではありません。それはする必要があります:

foldr :: (a -> b -> b) -> b -> Tree a -> b 

そして、それらのab型パラメータは、パラメータとして残っている必要があります。これはabのすべて選択肢のためを動作するように持っています。他のタイプのクラスに制約することはできませんし、そのうちの1つを具体的にIntタイプに制限することはできません。

1

実際のfoldr関数を変更するのではなく、実際の関数を使用して、望みの結果が得られるようです。型クラスメソッドのシグニチャを変更することはできません。この場合、必要はありません。その型の分かりやすい実装を提供してfoldrを実装し、foldrの最初の引数として渡すことができる関数addSizeを作成してみてください。 foldr addSize 0が必要な動作を行います。

関連する問題