2017-02-17 21 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. Будет ли это влиять, когда я попытаюсь использовать это над общим типом с монадой? Такие, как:

    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' отдельно от типов, которые они обертывают, и вы можете использовать их для написания пользовательских 'экземпляров'. Например, у вас возникнет проблема с записью экземпляра 'Monad' для' type C'. –

+0

Спасибо @BenjaminHodgson - Вы хотите принять ответ, и я соглашусь? –

ответ

3

Различия являются обычные различия между type и newtype.

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 s может быть частично применено.

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)