오늘 유형 유형의 데이터를 저장하지 않고 다른 유형의 데이터를 저장하는 것과 같은 방식으로 데이터 유형을 구성 할 수 있는지 조사하고 싶었습니다. . 그래서 여기에 a
타입의 타입 생성자를 가지고 있지만 ByteString
타입의 데이터 생성자를 가진 GADT에 대한 나의 시도가 있습니다.유형 제한이있는 GADT의 Functor 인스턴스
decode' :: (Serialize a) => Serialized a -> a
decode' (MkSerialized bs) = let Right r = (decode bs) in r
을 그리고 그것은 작동합니다 :
{-# LANGUAGE GADTs #-}
import Data.ByteString.Char8
import Data.Serialize
data Serialized a where
MkSerialized :: (Serialize a) => ByteString -> Serialized a
지금 나는 다음과 같은 방법으로
decode'
기능을 정의 할 수 있습니다
let s = MkSerialized (encode "test") :: Serialized String
print $ decode' s -- prints "test"
내 문제는 내가가 될 Serialized
을하고 싶은 것이 지금 Functor
의 인스턴스
하지만 (Serialize b) 오류가 발생합니다. 어떻게 Serialize
이 fmap
에 적용되도록 Functor 인스턴스를 제한 할 수 있습니까?
수 없습니다. 'Functor'는 타입 파라미터에 대한 제약 조건을 요구하지 않습니다. 'rmonad' 패키지에는 제한된 Functor 클래스가 있습니다. ['RFunctor'] (http://hackage.haskell.org/packages/archive/rmonad/0.8/doc/html/Control-RMonad.html#t:RFunctor) . 어쩌면 당신이 그것을 사용할 수 있습니다. –
이것은 당신의 질문과 관련이 없습니다 - 이것은 실제로'Functor'에서 가능하지 않습니다 - 그러나 나는 의무적으로 말합니다 :'Data.ByteString.Char8'을 디폴트로 사용하지 마십시오! 깨진 코드를 깨뜨린 모듈입니다. 때로는 일부 용도가 있지만 코드가 유니 코드의 오해를 조장하지 않는'Data.ByteString'과 함께 작동합니다. – shachaf
그게 무슨 가치가 있는지, 당신은'CoYoneda' 스타일의 데이터 타입을 만들 수 있습니다'data Serialized a MkSerialized :: Serialize x => ByteString -> (x -> a) -> Serialized a' ByteString과 a post-deserialization 함수를 가지고 있고, Functor 인스턴스를 가지고있다. 그러나 당연히 여기의 목적을 저지합니다. – shachaf