module value import StdGeneric, StdEnv :: Value = VInt Int | VReal Real | VUnit | VPair Value Value | VLeft Value | VRight Value | VFun (Value -> Value) | VCons Value | VField Value | VObject Value generic gConvertValue a :: Bimap a Value gConvertValue {|Int|} = {map_to = map_to, map_from = map_from } where map_to x = VInt x map_from (VInt x) = x map_from _ = abort "gConvertValue failed on Int" gConvertValue {|Real|} = {map_to = map_to, map_from = map_from } where map_to x = VReal x map_from (VReal x) = x map_from _ = abort "gConvertValue failed on Real" gConvertValue {|UNIT|} = {map_to = map_to, map_from = map_from } where map_to UNIT = VUnit map_from VUnit = UNIT map_from _ = abort "gConvertValue failed on UNIT" gConvertValue {|PAIR|} cx cy = {map_to = map_to, map_from = map_from } where map_to (PAIR x y) = VPair (cx.map_to x) (cy.map_to y) map_from (VPair x y) = PAIR (cx.map_from x) (cy.map_from y) map_from _ = abort "gConvertValue failed on PAIR" gConvertValue {|EITHER|} cl cr = {map_to = map_to, map_from = map_from } where map_to (LEFT x) = VLeft (cl.map_to x) map_to (RIGHT x) = VRight (cr.map_to x) map_from (VLeft x) = LEFT (cl.map_from x) map_from (VRight x) = RIGHT (cr.map_from x) map_from _ = abort "gConvertValue failed on EITHER" gConvertValue {|(->)|} ca cr = {map_to = map_to, map_from = map_from } where map_to f = VFun (cr.map_to o f o ca.map_from) map_from (VFun f) = (cr.map_from o f o ca.map_to) map_from _ = abort "gConvertValue failed on (->)" gConvertValue {|CONS|} ca = {map_to = map_to, map_from = map_from } where map_to (CONS x) = VCons (ca.map_to x) map_from (VCons x) = CONS (ca.map_from x) map_from _ = abort "gConvertValue failed on CONS" gConvertValue {|FIELD|} ca = {map_to = map_to, map_from = map_from } where map_to (FIELD x) = VField (ca.map_to x) map_from (VField x) = FIELD (ca.map_from x) map_from _ = abort "gConvertValue failed on FIELD" gConvertValue {|OBJECT|} ca = {map_to = map_to, map_from = map_from } where map_to (OBJECT x) = VObject (ca.map_to x) map_from (VObject x) = OBJECT (ca.map_from x) map_from _ = abort "gConvertValue failed on OBJECT" convertTo :: (a -> Value) | gConvertValue{|*|} a convertTo = gConvertValue{|*|}.map_to convertFrom :: (Value -> a) | gConvertValue{|*|} a convertFrom = gConvertValue{|*|}.map_from //-------------------------------------------------------------------------------- applyValue :: Value Value -> Value applyValue (VFun f) x = f x applyValue _ x = abort "applyValue: not a function\n" Start :: Int Start = convertFrom (applyValue (convertTo ((+) 1)) (convertTo 1))