0

I have a very simple continuation function (avoided using Monads for simplicity sake):

data C a = C {unwrap :: (a -> a) -> a}

Essentially, I'm trying to perform different implementations based on input type, something similar to (sudo-code):

data Gadt a where
  AString :: String -> Gadt Bool
  AInt :: Int -> Gadt Bool

data C a = C {unwrap :: (a -> Gadt a) -> a}

example :: a -> C a
example v = C $ \f -> | (v :: Int) == True      = f (AInt v)
                      | (v :: String) == True   = f (AString v)

cont :: Gadt a -> a
cont (AInt v)       = ...
cont (AString v)    = ...

Am I overlooking a basic solution here? I'm new to continuations so I may of just overlooked something simple.

Babra Cunningham
  • 2,949
  • 1
  • 23
  • 50

2 Answers2

1

First you cannot use :: as a predicate to test the runtime type (as far as I know). Second your a parameter of Gadt is entirely phantom. Is that intended? example can either be polymorphic by treating different types uniformly or you'd need to use class (parametric vs ad-hoc polymorphism). You might have wanted something like

data Gadt where
    AInt :: Int -> Gadt
    AString :: String -> Gadt

data C a = C { unwrap :: (a -> Gadt) -> Gadt }

class Ex a where
    example :: a -> C a

instance Ex Int where
    example v = C ...

instance Ex String where
    example v = C ...

This is still pseudo-code, as it makes little sense but at least type-checks for me.

jakubdaniel
  • 2,233
  • 1
  • 13
  • 20
0

I've come across a potential solution, following advice from here:

newtype C r a = C {runC :: (a -> r) -> r}

data Hole = Hole1 Int | Hole2 String | Hole3 Bool

example :: String -> C Bool a
example s = C $ \f -> do
   x <- f (Hole1 22)
   y <- f (Hole2 "string")
   k (Hole3 False)

cont :: Hole -> Bool
cont (Hole1 x) = ...
cont (Hole2 x) = ...
cont (Hole3 x) = ...

This enables specific implementations based on type by wrapping the input type inside the Hole data structure.

Babra Cunningham
  • 2,949
  • 1
  • 23
  • 50