2016-09-01 13 views
10

나는 예를 들어, 몇 가지 간단한 기본 작업이 있습니다 operational 모나드의 경우haskell "operational"또는 "free monad"연속을 디스크에 저장할 수 있습니까?

:

import Control.Monad.Operational 
type Process a = Program ProcessI a 
data ProcessI a where 
    GetInput :: ProcessI String 
    Dump :: String -> ProcessI() 
getInput :: Process String 
getInput = singleton GetInput 
dump :: String -> Process() 
dump = singleton . Dump 

또는 free 모나드의 경우

가 :

import Control.Monad.Free 
type Process = Free ProcessF 
data ProcessF a 
    = GetInput (String -> a) 
    | Dump String a 
    deriving (Functor) 
getInput :: Process String 
getInput = liftF $ GetInput id 
dump :: String -> Process() 
dump s = liftF $ Dump s() 

간단한 작업은 모두 동일합니다 예 :

proc1 :: Process() 
proc1 = forever $ do 
    a <- getInput 
    b <- getInput 
    dump $ a ++ b 
    dump $ b ++ a 

내 질문은입니다 : 특정 단계의 연속이 디스크에 직렬화되고 다음 프로그램 실행 중에 복원되는 방식으로 프로세스 (proc1)를 해석 할 수 있습니까? 예를 들어 주시겠습니까?

가능한 경우 가장 가까운 해결 방법은 무엇입니까?

다음 입력이 가능할 때만 프로그램을 시작하고 입력을 계속 적용한 후 다음 "getInput"까지 해석하고 종료하십시오.

모든 입력을 기록한 다음 계속 진행하기 전에 시스템을 동일한 상태로 되 돌리는 시나리오를 상상할 수 있지만이 경우 로그는 제한없이 커집니다. (EQ 인스턴스가없는) 연속성을 비교할 가능성이없고 프로세스가 무한하기 때문에 인터프리터에서 로그를 캠 팩할 수있는 방법을 찾지 못했습니다. 그것을시피

+3

그런 식으로 생각하지 않습니다. (분산 컴퓨팅을위한 일부 GHC 스페셜은 그것을 할 수 있을지 모르지만 — 나는 그것들을 결코 파헤칩니다.) 최선의 표준 접근법은 하스켈의'Monad' 클래스의 편의성과 보편성을 여러분이 해석 할 수있는 추상적 인 언어로 함수를 표현하는 커스텀 버전으로 바꾸는 것입니다. – dfeuer

답변

5

은 두 가지 문제점이있다 :

  • 연속성을 임의의 데이터 유형

    를 포함 할 수
  • 함수 (즉, 폐쇄)를 포함 할 수
  • 연속성을

특히 주어진 두 번째 제약, 아마도 아무 할 방법 정확히 당신이 원하는.

Can Haskell functions be serialized?에 대한 설명은 packman이라는 라이브러리를 가리 킵니다. Readme에서 :

...이 기능을 사용하여 (다른 프로그램 실행에서) 메모 작성 및 프로그램 실행을 선택한 장소에서 최적화 할 수 있습니다. 두 가지 용도 모두 위에 링크 된 슬라이드 세트에 예시되어 있습니다.

(The slides 그것이 내가 생각 언급한다.)

이 방법의 제한은 데이터의하지 모든 유형 (또는해야한다!) 직렬화, 특히 가변 유형 IORef, MVar 추천하고 STM 관련 유형이 있으며 때로는 썽크 및 클로저로 종료되어 런타임 예외가 발생합니다.

또한 라이브러리는을 만든 동일한 바이너리에 의해 의 연속 된 연속을 사용하므로 응용 프로그램에 실제 문제가되지 않을 수도 있습니다.

packman과 같이 약간 제한적이고 복잡한 접근 방식으로 원하는 것을 얻을 수도 있고 관심을 가질만한 모든 정보를 캡처하는 사용자 정의 유형과 직렬화하는 고유 한 사용자 정의 논리를 작성할 수도 있습니다.