Я буду над продолжениями, и я пришел через два различных подхода к типам структурирования продолжения:Структурирование типов продолжения?
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
...
Я понимаю, что последний подход Безразлично Использовать явный конструктор данных.
- Каковы практические различия этих подходов?
Будет ли это влиять, когда я попытаюсь использовать это над общим типом с монадой? Такие, как:
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
Различия между обычными различиями между 'type' и' newtype'. Синонимы 'type' - это просто новое имя для существующего типа; они не могут быть частично применены, и вы не можете сделать их «экземпляром» класса. 'newtype' отдельно от типов, которые они обертывают, и вы можете использовать их для написания пользовательских 'экземпляров'. Например, у вас возникнет проблема с записью экземпляра 'Monad' для' type C'. –
Спасибо @BenjaminHodgson - Вы хотите принять ответ, и я соглашусь? –