5

いくつかのデフォルト メソッドを実装したいのですが、定義内でType Class使用できないというエラーが発生します。record selectorstype classes

次のコードは基本的に、 some のレコードに要素を追加する関数type classを定義するものを作成します。コードは次のとおりです。addreprdata type

import qualified Data.Graph.Inductive     as DG

class Graph gr a b where
    empty :: DG.Gr a b
    empty = DG.empty

    repr :: gr -> DG.Gr a b

    -- following function declaration does NOT work:
    add :: a -> gr -> gr
    add el g = g{repr = DG.insNode el $ repr g}

コンパイラはエラーをスローします:

repr is not a record selector
In the expression: g {repr = DG.insNode el $ repr g}
In an equation for add:
    add el g = g {repr = DG.insNode el $ repr g}

Haskell でそのようなメソッドを宣言することは可能ですか?

明確化

data types同様の方法で動作する をいくつか持っているため、そのような設計が必要です。ABしましょうC data types。それぞれにレコードが必要です。repr :: DG.Gr a bここで、aとは、とbのそれぞれに対して異なります。ABC

A、orのような同じ関数Bを共有します(基本的に record に要素を追加または削除します)。これらのデータ型が多くの関数を共有する場合、関数を実装してthis のインスタンスを作成することは理にかなっています。これらの関数は、それぞれに対して自動的に実装されます。Cadddeletereprtype classtype classdata type

さらに、関数を呼び出すときにこれらのいくつかdata types(私が欲しいとしましょうB)がわずかに異なる動作をすることを望んでいます。for を作成するときに、addこの動作を実装するのは簡単です。instancetype classB

4

2 に答える 2

0

このようなものを試すことができます(例ではなくタプルリストを使用していますDG

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, TypeSynonymInstances #-}

class MyClass g a b | g -> a b where
      extract :: g -> [(a,b)]
      construct :: [(a,b)] -> g 

      empty :: g
      empty = construct []

      add :: (a,b) -> g  -> g
      add i d = construct $  [i] ++ (extract d) 

data A  = A {reprA :: [(Int,Int)]}

instance MyClass A Int Int  where
         extract = reprA
         construct = A

data B  = B {reprB :: [(String,String)]}

instance MyClass B String String  where
         extract = reprB
         construct = B
于 2013-07-20T16:47:31.177 に答える