| 1 | |
|---|
| 2 | {-# LANGUAGE EmptyDataDecls, TypeFamilies, TypeOperators, ScopedTypeVariables #-} |
|---|
| 3 | module Overflow where |
|---|
| 4 | import Control.Concurrent |
|---|
| 5 | |
|---|
| 6 | data (:*:) a b |
|---|
| 7 | data (:+:) a b |
|---|
| 8 | |
|---|
| 9 | data family PChan a |
|---|
| 10 | data instance PChan (a :+: b) = E (IO (PChan a)) (IO (PChan b)) |
|---|
| 11 | newtype instance PChan (a :*: b) = O (IO (Either (PChan a) (PChan b))) |
|---|
| 12 | |
|---|
| 13 | type family Dual a |
|---|
| 14 | type instance Dual (a :+: b) = Dual a :*: Dual b |
|---|
| 15 | type instance Dual (a :*: b) = Dual a :+: Dual b |
|---|
| 16 | |
|---|
| 17 | class Connect s where |
|---|
| 18 | newPChan :: (s ~ Dual c, c ~ Dual s) => IO (PChan s, PChan c) |
|---|
| 19 | |
|---|
| 20 | pchoose :: (t -> a) -> MVar a -> IO (t,b) -> IO b |
|---|
| 21 | pchoose = undefined |
|---|
| 22 | |
|---|
| 23 | instance (Connect a, Connect b) => Connect (a :*: b) where |
|---|
| 24 | newPChan = do |
|---|
| 25 | v <- newEmptyMVar |
|---|
| 26 | -- correct implementation: |
|---|
| 27 | -- return (O $ takeMVar v, E (pchoose Left v newPChan) (pchoose Right v newPChan)) |
|---|
| 28 | |
|---|
| 29 | -- type error leads to stack overflow (even without UndecidableInstances!) |
|---|
| 30 | return (O $ takeMVar v, E (pchoose Right v newPChan) (pchoose Left v newPChan)) |
|---|