2016-08-03 8 views
6

私はFree Monadsを使用して小さなDSLを構築しています。Freeを使用してDSLで多態関数を実装することは可能ですか

私はDSLで多型関数を使用できるようにしたいと考えています。私は理にかなってNot in scope: type variable ‘a’ エラーを取得する上で、私はそれをコード化している方法

{-# 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' 

私が構築したい何かの例がこれです。 Freeを使ってDSLに多相関数を持たせる方法はありますか?

私がこれをやりたい理由は、バックグラウンドでTQueueを使用するプロダクションインタープリタと、メモリデータ構造をテスト用に使用するテストインタープリタを持つことができるためです。

答えて

11

あなたは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 

makeFreemakeFreeConMyDslのための無料の多型モナドのアクションを生成することができますどちらを使って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

関連する問題