2016-08-03 3 views
6

Free Monads를 사용하여 작은 DSL을 작성합니다.Free를 사용하여 DSL에서 다형 함수를 구현할 수 있습니까?

내 DSL에서 다형 함수를 사용하고 싶습니다.

내가 구축하고 싶은 무언가의 예는 이것이다 :

{-# LANGUAGE TemplateHaskell #-} 

import   Control.Monad.Free.Church 

data Queue a = Queue a 

data MyDsl next = 
    NewQueue (Queue a -> next) | 
    WriteToQueue (Queue a) a next 

makeFree ''MyDsl 

testProgram :: F MyDsl 
testProgram = do 
    (intQueue :: Queue Int) <- newQueue 
    (charQueue :: Queue Char) <- newQueue 
    writeToQueue intQueue 1 
    writeToQueue charQueue 'c' 

내가 의미가 Not in scope: type variable ‘a’ 오류가 발생할 수 위 내가 그것을 인코딩 한 방법. Free를 사용하여 DSL에서 다형 함수를 사용하는 방법이 있습니까?

백그라운드에서 배경으로 TQueue를 사용하는 프로덕션 인터프리터와 테스트를 위해 메모리 데이터 구조를 사용하는 테스트 인터프리터를 사용할 수 있습니다.

답변

11

당신은 MyDsl에 대한 GADT

{-# LANGUAGE GADTs #-} 
{-# LANGUAGE StandaloneDeriving #-} 
{-# LANGUAGE DeriveFunctor #-} 

data Queue a = Queue a 

data MyDsl next where 
    NewQueue :: (Queue a -> next) -> MyDsl next 
    WriteToQueue :: (Queue a) -> a -> next -> MyDsl next 

deriving instance Functor MyDsl 

어느 makeFreemakeFreeCon 생성 할 수 있습니다 무료 다형성 모나드 행동으로 DSL을 나타낼 수 있습니다. 직접 작성해야합니다.

{-# LANGUAGE FlexibleContexts #-} 

import Control.Monad.Free.Class 

newQueue :: (MonadFree MyDsl m) => m (Queue a) 
newQueue = wrap $ NewQueue return 

writeToQueue :: (MonadFree MyDsl m) => Queue a -> a -> m() 
writeToQueue q v = liftF $ WriteToQueue q v() 

이제 테스트 프로그램을 작성할 수 있습니다.

{-# LANGUAGE ScopedTypeVariables #-} 

import Control.Monad.Free.Church 

-- testProgram can have a more general type 
-- testProgram :: (MonadFree MyDsl m) => m() 
testProgram :: F MyDsl() 
testProgram = do 
    (intQueue :: Queue Int) <- newQueue 
    (charQueue :: Queue Char) <- newQueue 
    writeToQueue intQueue 1 
    writeToQueue charQueue 'c' 

당신은 당신의 DSL을 찾을 수는 큐의 유형을 매개 변수화 할 경우 여러 통역을 쓰기 쉽다. 그렇게 할 경우, 모나드 타입으로부터 큐 유형을 결정하기 위해 타입 패밀리 또는 함수 종속성이 필요합니다.

data MyDsl q next where 
    NewQueue :: (q a -> next) -> MyDsl next 
    WriteToQueue :: (q a) -> a -> next -> MyDsl next 
+0

정확하게 내가 찾고있는 Cirdec에 감사드립니다. 대기열 유형을 매개 변수화하는 데 유용한 팁. – Brownie

관련 문제