Existential Quantification Patterns and Antipatterns

The Existential Type Class Antipattern

map show [1, 'h', True] -- This won't compile
data Showable = forall a. Show a => Showable ainstance Show Showable where
show (Showable x) = show x
map show [Showable 1, Showable 'h', Showable True] -- compiles!
[show 1, show 'h', show True]

Pattern 1: Intermediate Value

data Fold a b
-- | @Fold @ @ step @ @ initial @ @ extract@
= forall x. Fold (x -> a -> x) x (x -> b)

Pattern 2: Hidden Types Which Can Unhidden

data Hideable a = a ~ Int  => IntHideable a 
| a ~ Char => CharHideable
data AnyHideable = forall a. AnyHideable (Hideable a)
incHideable :: Hideable Int -> Int
incHideable (IntHideable x) = x + 1
foo :: AnyHideable -> IO ()
foo (AnyHideable x) = case x of -- x is of type Hideable a
...
incHideable :: Hideable Int -> Int
incHideable (IntHideable x) = x + 1
foo :: AnyHideable -> IO ()
foo (AnyHideable x) = case x of
IntHideable {} -> print $ incHideable x -- x is a (Hideable Int)
...
data Hideable a where
IntHideable :: Int -> Hideable Int
CharHideable :: Char -> Hideable Char

Pattern 3: Type Aligned Data Structures

data State = Closed | Listen | SynSent | SynReceived | Established
| CloseWait | LastAck | FinWait1 | FinWait2 | Closing
| TimeWait
data Path :: State -> State -> * where
ServerStart :: Path Closed Closed
PassiveOpen :: Path Closed Listen
ServerClose :: Path Listen Closed
ServerSynRecieved :: Path Listen SynReceived
ClientSynRecieved :: Path SynReceived SynReceived
SynResponded :: Path SynReceived Established
ToFinWait1 :: Path Established FinWait1
ActiveOpen :: Path Closed SynSent
PassiveToActive :: Path Listen SynSent
ClientClose :: Path SynSent Closed
FinishHandshake :: Path SynSent Established
PassiveClose :: Path Established CloseWait
ToLastAck :: Path CloseWait LastAck
EarlyClose :: Path SynReceived FinWait1
ActiveClose :: Path Established FinWait1
SimulatanousClose :: Path FinWait1 Closing
SimulatanousCloseAck :: Path Closing TimeWait
FastClose :: Path FinWait1 TimeWait
CloseAcknowledge :: Path FinWait1 FinWait2
FinishClose :: Path FinWait2 TimeWait
Waited :: Path TimeWait Closed
(:::) :: Path a b -> Path b c -> Path a c

connectAndClose :: Path Closed Closed
connectAndClose = ServerStart ::: ActiveOpen ::: ClientClose

Relation to RankNTypes

Conclusion

--

--

--

Haskeller Haskelling.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Revit + Dynamo + Python: Create your own Plug-ins by automating interference correction between…

Introduction to Big O notation

Tuesday update from PointPay

Code Smell 75 — Comments Inside a Method

Dev blog 4 (Week 5)

Creating and filling a Postgres DB with Docker compose

HTTP Error Code Caching with CloudFront (CDNs)

The Art Of Debugging

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Jonathan Fischoff

Jonathan Fischoff

Haskeller Haskelling.

More from Medium

What is C Programming?

What is C programming?

How Linked List Internally works, in C++

C++20 jthread and stop token: a gentle introduction

Why You Should Focus On One Programming Language.