2017-02-17 20 views
6

は私が継続上つもりだと私は構造化継続タイプに2つの異なるアプローチに遭遇しました:私は後者のアプローチはdoesnのことを理解し連続タイプの構造化?

type C r a = (a -> r) -> r 

exampleFunction :: String -> C Bool String 
exampleFunction s = \t -> if length s > 10 then t s else False 

... 

Poor Mans Concurrencyに採用されたアプローチ対

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

exampleFunction :: String -> C Bool String 
exampleFunction s = C $ \t -> if length s > 10 then t s else False 

continuationFunction :: String -> Bool 
continuationFunction s = True 

main = do 
let suspendedFunc = exampleFunction "testing" 
let completedFunc = runC suspendedFunc $ continuationFunction 

明示的なデータコンストラクタを使用しないでください。

  1. これらのアプローチの実際の違いは何ですか?
  2. 一般的なタイプのモナドでこれを使用しようとすると、この影響がありますか?以下のような:

    data Hole = Hole1 Int | Hole2 String 
    
    type C r m a = (a -> m r) -> m r 
    
    exampleFunction :: String -> C Bool Maybe Hole 
    exampleFunction s = \t -> do 
         x <- t (Hole1 11) 
         y <- t (Hole2 "test") 
         ... 
    
    continuationFunction :: Hole -> Bool 
    continuationFunction (Hole1 x) = False 
    continuationFunction (Hole2 y) = True 
    
+4

違いは、通常、 'type'と' newtype'の違いです。 'type'シノニムは、既存の型の新しい名前です。部分的には適用できず、クラスのインスタンスにすることはできません。 'newtype'はラップする型とは別のもので、カスタム'インスタンス 'を書くために使うことができます。たとえば、 'type C'の' Monad'のインスタンスを書くのに問題があります。 –

+0

ありがとう@BenjaminHodgson - あなたは答えにしたいと私は受け入れるだろうか? –

答えて

3

違いがtypenewtype間の通常の違いがあります。

typeシノニムは、既存のタイプの単なる新しい名前です。 typeシノニムは部分的には適用できません。コンパイラは型チェック中に定義を展開するためです。たとえば、これもTypeSynonymInstancesで、無意味です:

type TypeCont r a = (a -> r) -> r 

instance Monad (TypeCont r) where -- "The type synonym ‘TypeCont’ should have 2 arguments, but has been given 1" 
    return x = ($ x) 
    k >>= f = \q -> k (\x -> (f x) q) 

newtype S、彼らはラップタイプに動作同等ながら、型システム内の別々の実体です。つまり、newtypeの部分適用が可能です。

関連する問題