2015-01-08 2 views
1

의 내가 프레임에 대한 다형성 데이터 유형있어 가정 해 봅시다 :하스켈 : 다형성 데이터 유형에 대한 인스턴스를 읽고 튜플은

data Frame a = Frame { 
     fdata :: V.Vector (V.Vector a) 
    , frows :: Int 
    , fcols :: Int 
} 

makeFrame :: [[a]] -> Frame a 
makeFrame s = ... 

을 그리고 나는 그것의 텍스트 표현이 목록의 목록처럼 정확하게보고 싶다 :

-- works 
> let x = read $ show $ makeFrame [[1,2], [3,4]] :: Frame Int 
> :t x 
x :: Frame Int 

-- doesn't work 
> read $ show $ (1, makeFrame [[1,2], [3,4]]) :: (Int, Frame Int) 
*** Exception: Prelude.read: no parse 

-- meanwhile 
> let x = read $ show $ (1, makeFrame [[1,2], [3,4]]) :: (Int, [[Int]]) 
> :t x 
x :: (Int, [[Int]]) 
: 나는 프레임이 튜플 안에있을 때 정말 작동하지 않는 것을 발견 할 때까지
instance Show a => Show (Frame a) where 
    show (Frame m _ _) = show $ V.toList $ V.toList <$> m 

instance Read a => Read (Frame a) where 
    readsPrec _ value = [makeFrame $ read value, "")] 

나는 나의 읽기 기능을 꽤 행복했다

왜 내 데이터 형식을 터플에 무해하게 포함시키는 것이 모든 것을 파싱하는 방식을 변경합니까? 내가 뭘 놓치고 있니?

UPDATE :

그냥 경우, 작업 읽어 구현 :

instance Read a => Read (Frame a) where 
    readsPrec d v = do (lst, rst) <- readsPrec d v 
        return (makeFrame lst, rst) 

답변

5

귀하의 readsPrec 인스턴스가 항상 값이 끝난 후 모든 문자를 삭제 즉, 나머지 ""을 반환 그것은 읽었다. 자, 튜플 닫기를 의미하는 매달기 )입니다. 튜플을 파싱 할 수 없습니다. 왜냐하면 그 캐릭터를 버렸기 때문입니다.

구문 분석 할 항목의 readsPrec 인스턴스를 사용하여 소비 한 문자 수를 알아야합니다. 내가 당신과 유사 하나, 내가 같은 오류가 내 Read 인스턴스를 교체 할 경우

newtype Wrapper a = Wrapper a 

instance Show a => Show (Wrapper a) where 
    show (Wrapper x) = 'w':show x 

instance Read a => Read (Wrapper a) where 
    readsPrec n ('w':s) = [(Wrapper x, r) | (x, r) <- readsPrec n s] 

이 작동하지만 : 나는 컴파일 가능한되도록 어떠한 외부 의존성과 함께, 당신보다 간단 newtype은을 사용합니다 그것을 다른 데이터 구조 내부에서 구문 분석 할 수 없습니다.

+0

고맙습니다. 필자는 필자의 readsPrec이 어떤 이유로 든 호출되지 않는다고 생각했다. 왜냐하면 거기에 추적을 추가하면 아무 것도 표시하지 않기 때문이다 : readsPrec _ value = [(makeFrame $ read $ trace ("->"++ value) value,)]). 아마 그것은 예외가 표시되는 방식과 관련이 있습니다. –

+0

Btw, 목록을 읽을 수있는 간단한 함수가 있는지, * 문자 수를 나타내는 기호가 몇 개인 지 알 수 있습니까? –

+0

@ DanKruchinin : 목록 목록을 읽고 프레임 데이터 형식으로 변환하는 것이 더 쉽습니다. 'readsPrec = makeFrame과 같은 것. readsPrec'를 제외하고는 typecheck를 만들기 위해 전달해야하는 추가 인수를 제외합니다. –

관련 문제