Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ST-like encapsulation

I am trying to use the type system to ensure that X can never be taken out from the monad M. I'm expecting it to work similar to runST, where it is impossible to mix environments from different threads.

data X s = X Int
type M s = State Int

newX :: M s (X s)
newX = X <$> get

eval :: (forall s. M s a) -> a
eval x = evalState x 0

However the following code does not cause a type error:

ghci> x = eval newX
ghci> :t x
x :: X s

Why does similar code in the ST monad throw an error and mine does not? To my understanding the s in the M s a should become bound, making the s in X s a free type variable and thereby causing an error in the type checker.

like image 975
Souper Avatar asked Feb 04 '20 13:02

Souper


People also ask

What do you mean by encapsulation?

Encapsulation is a way to restrict the direct access to some components of an object, so users cannot access state values for all of the variables of a particular object. Encapsulation can be used to hide both data members and data functions or methods associated with an instantiated class or object.

What is an example of encapsulation?

Encapsulation in Java is a process of wrapping code and data together into a single unit, for example, a capsule which is mixed of several medicines.


1 Answers

To enforce type abstraction, you must use data or newtype, not type.

An unused parameter in a type synonym has no effect at all:

type M s = State Int

So these are equivalent:

newX :: M s (X s)
newX :: State Int (X s)

eval :: (forall s. M s a) -> a
eval :: State Int a -> a

eval is not actually higher-rank.

like image 89
Li-yao Xia Avatar answered Nov 03 '22 00:11

Li-yao Xia