私はハスケルタイプのクラスで遊んでいましたが、私は誰かが私を解決するのを助けてくれることを願っています。私は、素早い背景から来て、プロトコル指向の知識の一部をHaskellコードに移植しようとする "試み"を考えてください。タイプクラッセインスタンスのリスト
は当初、私はちょうど別の実装、同じ構造を持っていたJSONパーサーの束を宣言:
data Candle = Candle {
mts :: Integer,
open :: Double,
close :: Double
}
data Bar = Bar {
mts :: Integer,
min :: Double,
max :: Double
}
その後、私は彼らの基本的な操作の定義する「クラス」を作成することにしました:
class GenericData a where
dataName :: a -> String
dataIdentifier :: a -> Double
dataParsing :: a -> String -> Maybe a
dataEmptyInstance :: a
instance GenericData Candle where
dataName _ = "Candle"
dataIdentifier = fromInteger . mts
dataParsing _ = candleParsing
dataEmptyInstance = emptyCandle
instance GenericData Bar where
dataName _ = "Bar"
dataIdentifier = fromInteger . mts
dataParsing _ = barParsing
dataEmptyInstance = emptyBar
を
私の最初のコードの匂いは、必要でないときに "a"を含める必要がありましたが(dataName
またはdataParsing
)、その後は手続きしました。今
analyzeArguments :: GenericData a => [] -> [String] -> Maybe (a, [String])
analyzeArguments [] _ = Nothing
analyzeArguments _ [] = Nothing
analyzeArguments name data
| name == "Candles" = Just (head possibleCandidates, data)
| name == "Bar" = Just (last possibleRecordCandidates, data)
| otherwise = Nothing
possibleCandidates :: GenericData a => [a]
possibleCandidates = [emptyCandle, emptyBar]
私はどちらかのインスタンスが構文解析を実行するために選択すべきかを選択するときに、私はいつも
• Couldn't match expected type ‘a’ with actual type ‘Candle’
‘a’ is a rigid type variable bound by
the type signature for:
possibleCandidates :: forall a. GenericData a => [a]
at src/GenericRecords.hs:42:29
次のエラーを取得する私の目的は、他のためGenericData
のインスタンスのリストを作成することでした関数は、正しいdataParser
を実行するために選択されている関数に依存します。私はこれが型クラスチェッカーである* -> Constraint
と関係がありますが、この矛盾を解決する方法はまだ見つけていないことを理解しています。私はいくつかのGHC言語拡張を使用していますが、問題を解決したものはありません。
ここのコードの匂いはおそらくあなたのタイプのクラスだと思います。メソッドのすべてが 'a'を最初の引数として取る型クラスを見ると、誰かがオブジェクト指向クラスをHaskell型クラスに振り回そうとしているのか疑いがあります。同じADTの下に 'Bar'コンストラクタと' Candle'コンストラクタを配置したいと思うように思えます。 – Alec
これは、既知の[反パターン](https://lukepalmer.wordpress.com/2010/01/24/haskell-antipattern-existential-typeclass/)に向かって急速に下降すると思います。 – chi
何が間違っているかについての2つのコメント(解決策の提案なし)。 1.リストは同種(すべての要素が同じ型)なので、 '[emptyCandle、emptyBar]'が正しく出力されます。 2.型 'Foo a => [a]'は、この値のユーザに、 'Foo'のどのインスタンスが選択されているかを制御します。実装者は 'Foo'のインスタンスである* any *型の値のリストを生成する準備をしなければなりませんが、この型の実装者がインスタンスである*好みの*型を選ぶと思っているようですFooの –