Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eric-corumdigital/990126af5d60f77f51b8d4468060c922 to your computer and use it in GitHub Desktop.
Save eric-corumdigital/990126af5d60f77f51b8d4468060c922 to your computer and use it in GitHub Desktop.
PureScript Mutable Data!
module Main where
import Data.Generic.Rep (class Generic, Argument, Constructor, Product)
import Effect (Effect)
import Effect.Class.Console as Console
import Effect.Uncurried (EffectFn1, EffectFn2, EffectFn3, runEffectFn1, runEffectFn2, runEffectFn3)
import Prelude (Unit, bind, discard, (>>=))
import Type.Data.Peano.Nat (class IsNat, NProxy, Succ, Z, d0, reflectNat, kind Nat)
-- Any product data type with a Generic instance can be made mutable!
data MyType a = MyType a
derive instance genericMyType ∷ Generic (MyType a) _
-- > main
-- 5
-- 10
-- 15
-- 10
-- 5
-- unit
main :: Effect Unit
main = do
let initial = MyType 5
mut ← thaw initial
getN d0 mut >>= Console.logShow
setN d0 10 mut
getN d0 mut >>= Console.logShow
final ← freeze mut
setN d0 15 mut
getN d0 mut >>= Console.logShow
Console.logShow (let MyType x = final in x)
Console.logShow (let MyType x = initial in x)
--
-- Type constructor for mutable data. `Mut (MyType Int)` for example.
foreign import data Mut ∷ Type → Type
foreign import thaw_ ∷ ∀ a. EffectFn1 a (Mut a)
-- | Create mutable data from immutable data.
thaw ∷ ∀ a rep. Generic a rep ⇒ a → Effect (Mut a)
thaw = runEffectFn1 thaw_
foreign import freeze_ ∷ ∀ a. EffectFn1 (Mut a) a
-- | Create immutable data from mutable data.
freeze ∷ ∀ a rep. Generic a rep ⇒ Mut a → Effect a
freeze = runEffectFn1 freeze_
class DataArg (n ∷ Nat) (a ∷ Type) (x ∷ Type) | n a → x
instance dataArg0 ∷ (Generic a rep, ConstructorArg n rep x) ⇒ DataArg n a x
class ConstructorArg (n ∷ Nat) (rep ∷ Type) (x ∷ Type) | n rep → x
instance constructorArg0_1 ∷ ProductArg n prod x ⇒ ConstructorArg n (Constructor c prod) x
class ProductArg (n ∷ Nat) (rep ∷ Type) (x ∷ Type) | n rep → x
instance productArg0_1 ∷ ProductArg Z (Argument x) x
else instance productArg0_2 ∷ ProductArg Z (Product (Argument x) b) x
else instance productArg0_3 ∷ ProductArg n b x ⇒ ProductArg (Succ n) (Product a b) x
foreign import setN_ ∷ ∀ a x. EffectFn3 Int x (Mut a) Unit
-- | Set the nth field of mutable data.
setN ∷ ∀ n a x. IsNat n ⇒ DataArg n a x ⇒ NProxy n → x → Mut a → Effect Unit
setN n = runEffectFn3 setN_ (reflectNat n)
foreign import getN_ ∷ ∀ a x. EffectFn2 Int (Mut a) x
-- | Get the nth field of mutable data.
getN ∷ ∀ n a x. IsNat n ⇒ DataArg n a x ⇒ NProxy n → Mut a → Effect x
getN n = runEffectFn2 getN_ (reflectNat n)
@eric-corumdigital
Copy link
Author

'use strict';

function copy(m) {
return Reflect.construct(m.constructor, Object.values(m));
}

exports.thaw_ = copy;

exports.freeze_ = copy;

exports.setN_ = function (n, x, m) {
m['value' + n] = x;
};

exports.getN_ = function (n, m) {
return m['value' + n];
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment