theory Scratch imports Main begin record foo = foo1 :: int foo2 :: int foo3 :: bool record foo_bar = foo + bar1 :: nat bar2 :: "bool set" text {* Problem: Convert @{typ "'a foo_scheme"} into @{typ "'b foo_scheme"}. A special variant is @{typ foo} (= @{typ "unit foo_scheme"}) to @{typ foo_bar} (= @{typ "unit foo_bar_ext foo_scheme"})*} definition cast1 :: "foo \ foo_bar" where "cast1 g = foo.extend g (foo_bar.fields 0 {})" export_code cast1 checking SML -- "fails" definition cast2 :: "foo \ foo_bar" where "cast2 = g(| bar1 := 0, bar2 := {} |)" -- "fails: Type mismatch" definition cast3 :: "foo \ foo_bar" where "cast3 g = g\ \ := \ bar1 = 0, bar2 = {}\\" -- "fails: Syntax error" definition cast4:: "foo \ foo_bar" where "cast4 g = foo.more_update (\_. \ bar1 = 0, bar2 = {} \) g" -- "fails: Type mismatch" text {* The previous definition fails, as @{const foo.more_update} has type @{typ "('a \ 'a) \ 'a foo_scheme \ 'a foo_scheme"} and not @{typ "('a \ 'b) \ 'a foo_scheme \ 'b foo_scheme"} *} text {* The following works, but is rather clumsy. In particular, it needs to specify all fields of @{typ foo}.*} function cast5 where "cast5 \ foo1 = x1, foo2 = x2, foo3 = x3 \ = \ foo1 = x1, foo2 = x2, foo3 = x3, bar1 = 0, bar2 = {}\" by (metis foo.cases) (metis foo.ext_inject) termination by lexicographic_order export_code cast5 checking SML -- "works" end