2017-02-17 36 views
6

我要去了延續和我遇到兩種不同的方法來構造延續類型:構造連續類型?

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 

與在Poor Mans Concurrency採取的做法:

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

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

... 

據我所知,後者的做法沒有按不使用顯式數據構造函數。

  1. 這些方法的實際區別是什麼?
  2. 當我嘗試在monad的一般類型上使用它時,這會影響嗎?如:

    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'與它們包裝的類型是分開的,你可以使用它們來編寫自定義的'實例'。例如,你爲'C類'編寫'Monad'的實例會遇到困難。 –

+0

謝謝@BenjaminHodgson - 你想成爲一個答案,我會接受嗎? –

回答

3

的差別是typenewtype之間的通常的差異。

A 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可以部分應用

newtype NewtypeCont r a = Cont { runCont :: (a -> r) -> r } 

instance Monad (NewtypeCont r) where 
    return x = Cont ($ x) 
    Cont k >>= f = Cont $ \q -> k (\x -> runCont (f x) q)