2017-02-27 13 views
0

私は(簡単のためにモナドを使用して回避)非常に単純な継続機能を持っている:入力タイプに基づく継続機能の実装?

:基本的に

data C a = C {unwrap :: (a -> a) -> a} 

、私は、入力タイプに基づいて異なる実装を実行する(sudoのコード)に似た何かをしようとしています

data Gadt a where 
    AString :: String -> Gadt Bool 
    AInt :: Int -> Gadt Bool 

data C a = C {unwrap :: (a -> Gadt a) -> a} 

example :: a -> C a 
example v = C $ \f -> | (v :: Int) == True  = f (AInt v) 
         | (v :: String) == True = f (AString v) 

cont :: Gadt a -> a 
cont (AInt v)  = ... 
cont (AString v) = ... 

ここでは基本的な解決策を見落としていますか?私は継続的に新しいので、私は単純なことを見過ごしているかもしれません。

+0

'f :: a - Gadt a'ではないのですが、なぜそれが' AInt v :: Gadt a'や 'AString v :: Gadt a'に作用するのでしょうか? – jakubdaniel

答えて

0

私はhereからアドバイスを、以下の、潜在的な解決策に遭遇しました:

newtype C r a = C {runC :: (a -> r) -> r} 

data Hole = Hole1 Int | Hole2 String | Hole3 Bool 

example :: String -> C Bool a 
example s = C $ \f -> do 
    x <- f (Hole1 22) 
    y <- f (Hole2 "string") 
    k (Hole3 False) 

cont :: Hole -> Bool 
cont (Hole1 x) = ... 
cont (Hole2 x) = ... 
cont (Hole3 x) = ... 

これはHoleデータ構造内の入力タイプをラップすることにより、タイプに基づいて具体的な実装を可能にします。

1

まず、ランタイムタイプをテストするための述語として(私が知る限り)::を使用することはできません。 2番目のaパラメータはGadtで完全にファントムです。それは意図されていますか? exampleは、異なるタイプを一様に扱うことによって多型であるか、またはclassparametricと対ad-hoc多型)を使用する必要があります。

data Gadt where 
    AInt :: Int -> Gadt 
    AString :: String -> Gadt 

data C a = C { unwrap :: (a -> Gadt) -> Gadt } 

class Ex a where 
    example :: a -> C a 

instance Ex Int where 
    example v = C ... 

instance Ex String where 
    example v = C ... 

これはほとんど意味をなさないが、少なくとも私のためにタイプチェックするので、疑似コードです。

関連する問題