构建延续类型?

时间:2017-02-17 08:39:51

标签: haskell types continuations newtype type-synonyms

我正在进行延续,我遇到了两种不同的方法来构建延续类型:

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  
    

1 个答案:

答案 0 :(得分: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虽然在操作上等同于它们包装的类型,但它们是类型系统中的独立实体。这意味着可以部分应用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)