2016-10-18 2 views
2

창조되고 한 가지로 돌아 다니는가?하스켈 기록 기능 제약

그것은 구성상의 이유로 유용 할 것 같습니다 예를 들어, 나는

내가 녹음 기능에 제약이 없기 때문에 그것은 작동하지 않습니다
(:+:) :: SinkBuilder -> SinkBuilder -> SinkBuilder 
a :+: b = SinkBuilder $ do 
    sa <- openSink a 
    sb <- openSink b 
    return $ Sink (\v -> writeSink sa >> writeSink sb) (closeSink sa >> closeSink sb) 

같은 것을 구현할 수 있지만, 그것은 또한 매우 매우 추한 외모 나는 그것을하는 훨씬 더 좋은 방법이 있어야한다고 확신한다.

+1

'MonadIO m => m 싱크'가 'IO 싱크'와 동일하지 않습니까? – Michael

+0

@Michael 나는 'm'이 보편적으로 정량화된다면 그것들이 동등하다고 생각한다. – chi

+0

그다지 동등하지 않습니다. 저는 MonadIO 인 자체 모나드를 가지고 있습니다. 또한 제약 조건이 더 필요했습니다. 예를 들어'(MonadIO m, MonadState MyState m) => ... ' –

답변

0

이 내용은 컴파일되지만 실제로하고 싶은 작업에 대한 명확한 아이디어가 없습니다. 나는 이것이 당신이 원하는 것이 아니라는 것을 두려워합니다.

{-# LANGUAGE ScopedTypeVariables, RankNTypes #-} 

import Control.Monad.Trans 

type Value = Int 

data SinkBuilder = SB 
    { openSink :: forall m. MonadIO m => m Sink 
    } 

data Sink = Sink 
    { writeSink :: forall m. MonadIO m => Value -> m() 
    , closeSink :: forall m. MonadIO m => m() 
    } 

(#+#) :: SinkBuilder -> SinkBuilder -> SinkBuilder 
a #+# b = SB $ do 
    sa <- openSink a 
    sb <- openSink b 
    return $ Sink (\v -> writeSink sa v >> writeSink sb v) (closeSink sa >> closeSink sb) 
+0

고마워, 나는 이것을 시도 할 것이다. 내가 원했던 것은 효과가있는 '씽크 (Sink)'에 대한 개념을 갖는 것입니다. 열 수있는 것, 그리고 나서 가치를 부여하고 닫을 수 있습니다. 예를 들어, XML 파일에 쓰는 싱크, Json 파일에 쓰는 싱크 등을 가질 수 있습니다. 또한 '싱크 + 싱크 = 싱크'와 같은 방법으로 구성 할 수 있기를 원합니다. 그래서 보낼 때 결과 싱크에 두 (또는 많은) 파일이 기록됩니다. 일부 Sink는'MonadState S m =>'제약 조건을 요구하는 방식으로 "stateful"이 될 수 있기 때문에 여기에 제약 조건이 도입되었습니다. 더 잘 모델링하는 법을 모르겠습니다 ... –