Created
December 11, 2019 17:12
-
-
Save eric-corumdigital/990126af5d60f77f51b8d4468060c922 to your computer and use it in GitHub Desktop.
PureScript Mutable Data!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
'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];
};