저는 하스켈 타입 클래스를 가지고 놀았으며, 누군가가 저를 도울 수 있기를 바랍니다. 내가 신속한 배경에서 출발하여 하스켈 코드에 프로토콜 지향 지식을 포팅하려고하는 "시도"를 생각해보십시오. 타입 클래스 인스턴스 목록
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
처음에 나는 동일한 구조, 단지 다른 구현을했다 JSON 파서의 무리를 선언
첫 번째 코드 냄새가 필요하지 않을 때 "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]
, 난 항상 내 목표는 다른 때문에 GenericData
의 인스턴스 목록을 만드는 것이 었습니다
• 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
다음과 같은 오류가 함수는 올바른 dataParser
을 실행하도록 선택된 함수에 따라 달라집니다. 이 유형의 검사기 인 * -> Constraint
과 관련이 있지만이 충돌을 해결할 방법을 찾지 못했다는 것을 알고 있습니다. 몇 가지 GHC 언어 확장을 사용했지만 아무도 문제를 해결하지 못했습니다.
여기 코드 냄새가 아마도 당신의 타입 클래스라고 생각합니다. 메소드가 모두'a'를 첫 번째 인자로 가지는 타입 클래스를 볼 때마다, 누군가가 객체 지향 클래스를 하스켈 타입 클래스로 구형화하려고 시도하고 있다는 것을 의심스러워합니다. 같은 ADT 하에서'Bar'와'Candle' 생성자를 넣으려는 것 같습니다. – Alec
나는 이것이 알려진 반 패턴 (https://lukepalmer.wordpress.com/2010/01/24/haskell-antipattern-existential-typeclass/)을 향해 빠르게 내려갈 것이라고 생각한다. – chi
무엇이 잘못되었는지에 대한 두 가지 의견 (해결책 제시 없음). 1.리스트는 동 질적 (모든 엘리먼트는 같은 타입을 가짐)이므로'[emptyCandle, emptyBar]'가 바로 나온다. 2.'Foo a => [a]'타입은이 값의 사용자에게'Foo'의 인스턴스가 선택되는 것을 제어합니다; 구현자는'Foo'의 인스턴스 인 * any * 타입의 값 목록을 생성 할 준비가되어 있어야합니다. 반면에이 유형의 구현자가 인스턴스 인 선호 유형을 선택한다고 생각하는 것 같습니다 'Foo'. –