Created
June 18, 2018 16:44
-
-
Save parsonsmatt/8f6122f8fb0f9c4c87042050a2d944c8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE DataKinds #-} | |
{-# LANGUAGE KindSignatures #-} | |
{-# LANGUAGE TypeFamilies #-} | |
{-# LANGUAGE UndecidableInstances #-} | |
{-# LANGUAGE GADTs #-} | |
{-# OPTIONS_GHC -Wall #-} | |
module Main where | |
import GHC.TypeLits | |
import GHC.Exts | |
main :: IO () | |
main = return () | |
data Status = Pending | Completed | Canceled | |
data Job (status :: Status) where | |
JobPending :: Id -> URL -> Job 'Pending | |
JobCompleted :: Id -> Timestamp -> Job 'Completed | |
JobCanceled :: Id -> Reason -> Timestamp -> Job 'Canceled | |
type Timestamp = Int | |
type Reason = String | |
type Id = Int | |
type URL = String | |
runJob :: Job 'Pending -> IO (Job 'Completed) | |
runJob (JobPending i req) = do | |
putStrLn ("Running job: " ++ show i) | |
putStrLn ("Making request: " ++ req) | |
let now = 300 | |
return (JobCompleted i now) | |
cancelJob :: Reason -> Job 'Pending -> IO (Job 'Canceled) | |
cancelJob reason (JobPending i _) = do | |
putStrLn ("Canceling job: " ++ show i) | |
let now = 400 | |
return (JobCanceled i reason now) | |
jobTimestamp :: HasTimestamp status => Job status -> Timestamp | |
jobTimestamp (JobCompleted _ t) = t | |
jobTimestamp (JobCanceled _ _ t) = t | |
type family HasTimestamp (status :: Status) :: Constraint where | |
HasTimestamp 'Pending = TypeError ('Text "No timestamp for Pending") | |
HasTimestamp 'Completed = () | |
HasTimestamp 'Canceled = () |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment