정확히 여기 물어 보는 건 어렵습니다. 확실히 특정 유형 T
을 선택하고 ByteString
을 비 직렬화하여 AnyNode
에 저장할 수 있습니다. 어쨌든 AnyNode
의 사용자는 좋지 않습니다. 결국 당신은 여전히 T
을 골랐습니다. Typeable
제약 조건이 아니라면 사용자는 형식이 무엇인지 알 수 없기 때문에 (Typeable
제약 조건을 없애기 때문에 더 복잡해집니다). 어쩌면 당신이 원하는 것은 실존 적이 아니라 보편적 인 것일 수 있습니다. (그래서 예를 들어, read
이 실패 할 수 없습니다) 그들에게 조금 단순화 - 그들 Read
및 Show
전화 -
이의 두 클래스로 최대
Serialize
분할 보자.
그래서 우리는
class Show a where show :: a -> String
class Read a where read :: String -> a
우리는 Show
-able 값에 대한 실존 적 컨테이너를 만들 수 있습니다
data ShowEx where
ShowEx :: forall a. Show a => a -> ShowEx
-- non-GADT: data ShowEx = forall a. Show a => ShowEx a
하지만 물론 ShowEx
의
이
String
에 동형, 그래서 전체가 아니다 이 점은 이것을 가리킨다. 그러나
Read
에 대한 실존 적 짝수 적은 포인트가되어 있습니다 : - 즉
∃a. Read a *> a
- 내가 당신에게
ReadEx
을 줄 때
data ReadEx where
ReadEx :: forall a. Read a => a -> ReadEx
-- non-GADT: data ReadEx = forall a. Read a => ReadEx a
을 당신이 어떤 타입의 값을 가지고 있음을 의미하며, 당신이 모르는 무엇을 유형은 0이지만 String
을 동일한 유형의 다른 값으로 사용할 수 있습니다. 그러나 당신은 그것으로 무엇이든 할 수 없다! read
만a
을 생성하지만 어떤 것이 a
인지 모르는 경우에는 좋은 결과를 얻지 못합니다.
Read
으로 무엇을 할 수 있겠습니까? 발신자가 선택할 수있는 유형, 즉 범용입니다.
newtype ReadUn where
ReadUn :: (forall a. Read a => a) -> ReadUn
-- non-GADT: newtype ReadUn = ReadUn (forall a. Read a => a)
같은 뭔가 (- 즉 ∀a. Show a => a
-처럼 ReadEx
, 당신은 ShowUn
을 만들 수 있으며 그냥 쓸모가있을 것입니다.) ShowEx
은 본질적으로 show
의 인수 것을
주 - 즉 show :: (∃a. Show a *> a) -> String
- - 그리고 ReadUn
은 기본적으로 read
- 즉 read :: String -> (∀a. Read a => a)
의 반환 값입니다.
그래서 당신은 무엇을 요구하고 있습니까? 존재 적입니까, 보편적입니까? 당신은 확실히 ∀a. (Show a, Read a) => a
또는 ∃a. (Show a, Read a) *> a
과 같은 것을 만들 수 있습니다. 진짜 문제는 한정어이다.
(나는 다른 맥락에서이 중 일부에 대해 이야기 어디서 얼마 전에
a question를 물었다.) 당신은 (실제 유형에 전달할 수 있도록 직렬화 기능의 중앙 집중식 "레지스트리"어떤 종류의가 필요
2006 년 토론에서 그들은 비슷한 제안을했습니다. 앞으로 더 나은 솔루션이 나타날 경우를 대비하여 질문을 공개하겠습니다. –