src/Doc/Classes/Classes.thy
changeset 61076 bdc1e2f0a86a
parent 58842 22b87ab47d3b
child 61411 289b92ddb57c
equal deleted inserted replaced
61075:f6b0d827240e 61076:bdc1e2f0a86a
     8   Type classes were introduced by Wadler and Blott @{cite wadler89how}
     8   Type classes were introduced by Wadler and Blott @{cite wadler89how}
     9   into the Haskell language to allow for a reasonable implementation
     9   into the Haskell language to allow for a reasonable implementation
    10   of overloading\footnote{throughout this tutorial, we are referring
    10   of overloading\footnote{throughout this tutorial, we are referring
    11   to classical Haskell 1.0 type classes, not considering later
    11   to classical Haskell 1.0 type classes, not considering later
    12   additions in expressiveness}.  As a canonical example, a polymorphic
    12   additions in expressiveness}.  As a canonical example, a polymorphic
    13   equality function @{text "eq \<Colon> \<alpha> \<Rightarrow> \<alpha> \<Rightarrow> bool"} which is overloaded on
    13   equality function @{text "eq :: \<alpha> \<Rightarrow> \<alpha> \<Rightarrow> bool"} which is overloaded on
    14   different types for @{text "\<alpha>"}, which is achieved by splitting
    14   different types for @{text "\<alpha>"}, which is achieved by splitting
    15   introduction of the @{text eq} function from its overloaded
    15   introduction of the @{text eq} function from its overloaded
    16   definitions by means of @{text class} and @{text instance}
    16   definitions by means of @{text class} and @{text instance}
    17   declarations: \footnote{syntax here is a kind of isabellized
    17   declarations: \footnote{syntax here is a kind of isabellized
    18   Haskell}
    18   Haskell}
    19 
    19 
    20   \begin{quote}
    20   \begin{quote}
    21 
    21 
    22   \noindent@{text "class eq where"} \\
    22   \noindent@{text "class eq where"} \\
    23   \hspace*{2ex}@{text "eq \<Colon> \<alpha> \<Rightarrow> \<alpha> \<Rightarrow> bool"}
    23   \hspace*{2ex}@{text "eq :: \<alpha> \<Rightarrow> \<alpha> \<Rightarrow> bool"}
    24 
    24 
    25   \medskip\noindent@{text "instance nat \<Colon> eq where"} \\
    25   \medskip\noindent@{text "instance nat :: eq where"} \\
    26   \hspace*{2ex}@{text "eq 0 0 = True"} \\
    26   \hspace*{2ex}@{text "eq 0 0 = True"} \\
    27   \hspace*{2ex}@{text "eq 0 _ = False"} \\
    27   \hspace*{2ex}@{text "eq 0 _ = False"} \\
    28   \hspace*{2ex}@{text "eq _ 0 = False"} \\
    28   \hspace*{2ex}@{text "eq _ 0 = False"} \\
    29   \hspace*{2ex}@{text "eq (Suc n) (Suc m) = eq n m"}
    29   \hspace*{2ex}@{text "eq (Suc n) (Suc m) = eq n m"}
    30 
    30 
    31   \medskip\noindent@{text "instance (\<alpha>\<Colon>eq, \<beta>\<Colon>eq) pair \<Colon> eq where"} \\
    31   \medskip\noindent@{text "instance (\<alpha>::eq, \<beta>::eq) pair :: eq where"} \\
    32   \hspace*{2ex}@{text "eq (x1, y1) (x2, y2) = eq x1 x2 \<and> eq y1 y2"}
    32   \hspace*{2ex}@{text "eq (x1, y1) (x2, y2) = eq x1 x2 \<and> eq y1 y2"}
    33 
    33 
    34   \medskip\noindent@{text "class ord extends eq where"} \\
    34   \medskip\noindent@{text "class ord extends eq where"} \\
    35   \hspace*{2ex}@{text "less_eq \<Colon> \<alpha> \<Rightarrow> \<alpha> \<Rightarrow> bool"} \\
    35   \hspace*{2ex}@{text "less_eq :: \<alpha> \<Rightarrow> \<alpha> \<Rightarrow> bool"} \\
    36   \hspace*{2ex}@{text "less \<Colon> \<alpha> \<Rightarrow> \<alpha> \<Rightarrow> bool"}
    36   \hspace*{2ex}@{text "less :: \<alpha> \<Rightarrow> \<alpha> \<Rightarrow> bool"}
    37 
    37 
    38   \end{quote}
    38   \end{quote}
    39 
    39 
    40   \noindent Type variables are annotated with (finitely many) classes;
    40   \noindent Type variables are annotated with (finitely many) classes;
    41   these annotations are assertions that a particular polymorphic type
    41   these annotations are assertions that a particular polymorphic type
    55   symmetry and transitivity:
    55   symmetry and transitivity:
    56 
    56 
    57   \begin{quote}
    57   \begin{quote}
    58 
    58 
    59   \noindent@{text "class eq where"} \\
    59   \noindent@{text "class eq where"} \\
    60   \hspace*{2ex}@{text "eq \<Colon> \<alpha> \<Rightarrow> \<alpha> \<Rightarrow> bool"} \\
    60   \hspace*{2ex}@{text "eq :: \<alpha> \<Rightarrow> \<alpha> \<Rightarrow> bool"} \\
    61   @{text "satisfying"} \\
    61   @{text "satisfying"} \\
    62   \hspace*{2ex}@{text "refl: eq x x"} \\
    62   \hspace*{2ex}@{text "refl: eq x x"} \\
    63   \hspace*{2ex}@{text "sym: eq x y \<longleftrightarrow> eq x y"} \\
    63   \hspace*{2ex}@{text "sym: eq x y \<longleftrightarrow> eq x y"} \\
    64   \hspace*{2ex}@{text "trans: eq x y \<and> eq y z \<longrightarrow> eq x z"}
    64   \hspace*{2ex}@{text "trans: eq x y \<and> eq y z \<longrightarrow> eq x z"}
    65 
    65 
   109   \noindent This @{command class} specification consists of two parts:
   109   \noindent This @{command class} specification consists of two parts:
   110   the \qn{operational} part names the class parameter (@{element
   110   the \qn{operational} part names the class parameter (@{element
   111   "fixes"}), the \qn{logical} part specifies properties on them
   111   "fixes"}), the \qn{logical} part specifies properties on them
   112   (@{element "assumes"}).  The local @{element "fixes"} and @{element
   112   (@{element "assumes"}).  The local @{element "fixes"} and @{element
   113   "assumes"} are lifted to the theory toplevel, yielding the global
   113   "assumes"} are lifted to the theory toplevel, yielding the global
   114   parameter @{term [source] "mult \<Colon> \<alpha>\<Colon>semigroup \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>"} and the
   114   parameter @{term [source] "mult :: \<alpha>::semigroup \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>"} and the
   115   global theorem @{fact "semigroup.assoc:"}~@{prop [source] "\<And>x y z \<Colon>
   115   global theorem @{fact "semigroup.assoc:"}~@{prop [source] "\<And>x y z ::
   116   \<alpha>\<Colon>semigroup. (x \<otimes> y) \<otimes> z = x \<otimes> (y \<otimes> z)"}.
   116   \<alpha>::semigroup. (x \<otimes> y) \<otimes> z = x \<otimes> (y \<otimes> z)"}.
   117 *}
   117 *}
   118 
   118 
   119 
   119 
   120 subsection {* Class instantiation \label{sec:class_inst} *}
   120 subsection {* Class instantiation \label{sec:class_inst} *}
   121 
   121 
   128 
   128 
   129 instantiation %quote int :: semigroup
   129 instantiation %quote int :: semigroup
   130 begin
   130 begin
   131 
   131 
   132 definition %quote
   132 definition %quote
   133   mult_int_def: "i \<otimes> j = i + (j\<Colon>int)"
   133   mult_int_def: "i \<otimes> j = i + (j::int)"
   134 
   134 
   135 instance %quote proof
   135 instance %quote proof
   136   fix i j k :: int have "(i + j) + k = i + (j + k)" by simp
   136   fix i j k :: int have "(i + j) + k = i + (j + k)" by simp
   137   then show "(i \<otimes> j) \<otimes> k = i \<otimes> (j \<otimes> k)"
   137   then show "(i \<otimes> j) \<otimes> k = i \<otimes> (j \<otimes> k)"
   138     unfolding mult_int_def .
   138     unfolding mult_int_def .
   161 
   161 
   162 instantiation %quote nat :: semigroup
   162 instantiation %quote nat :: semigroup
   163 begin
   163 begin
   164 
   164 
   165 primrec %quote mult_nat where
   165 primrec %quote mult_nat where
   166   "(0\<Colon>nat) \<otimes> n = n"
   166   "(0::nat) \<otimes> n = n"
   167   | "Suc m \<otimes> n = Suc (m \<otimes> n)"
   167   | "Suc m \<otimes> n = Suc (m \<otimes> n)"
   168 
   168 
   169 instance %quote proof
   169 instance %quote proof
   170   fix m n q :: nat 
   170   fix m n q :: nat 
   171   show "m \<otimes> n \<otimes> q = m \<otimes> (n \<otimes> q)"
   171   show "m \<otimes> n \<otimes> q = m \<otimes> (n \<otimes> q)"
   195 
   195 
   196 definition %quote
   196 definition %quote
   197   mult_prod_def: "p\<^sub>1 \<otimes> p\<^sub>2 = (fst p\<^sub>1 \<otimes> fst p\<^sub>2, snd p\<^sub>1 \<otimes> snd p\<^sub>2)"
   197   mult_prod_def: "p\<^sub>1 \<otimes> p\<^sub>2 = (fst p\<^sub>1 \<otimes> fst p\<^sub>2, snd p\<^sub>1 \<otimes> snd p\<^sub>2)"
   198 
   198 
   199 instance %quote proof
   199 instance %quote proof
   200   fix p\<^sub>1 p\<^sub>2 p\<^sub>3 :: "\<alpha>\<Colon>semigroup \<times> \<beta>\<Colon>semigroup"
   200   fix p\<^sub>1 p\<^sub>2 p\<^sub>3 :: "\<alpha>::semigroup \<times> \<beta>::semigroup"
   201   show "p\<^sub>1 \<otimes> p\<^sub>2 \<otimes> p\<^sub>3 = p\<^sub>1 \<otimes> (p\<^sub>2 \<otimes> p\<^sub>3)"
   201   show "p\<^sub>1 \<otimes> p\<^sub>2 \<otimes> p\<^sub>3 = p\<^sub>1 \<otimes> (p\<^sub>2 \<otimes> p\<^sub>3)"
   202     unfolding mult_prod_def by (simp add: assoc)
   202     unfolding mult_prod_def by (simp add: assoc)
   203 qed      
   203 qed      
   204 
   204 
   205 end %quote
   205 end %quote
   235 
   235 
   236 instantiation %quote nat and int :: monoidl
   236 instantiation %quote nat and int :: monoidl
   237 begin
   237 begin
   238 
   238 
   239 definition %quote
   239 definition %quote
   240   neutral_nat_def: "\<one> = (0\<Colon>nat)"
   240   neutral_nat_def: "\<one> = (0::nat)"
   241 
   241 
   242 definition %quote
   242 definition %quote
   243   neutral_int_def: "\<one> = (0\<Colon>int)"
   243   neutral_int_def: "\<one> = (0::int)"
   244 
   244 
   245 instance %quote proof
   245 instance %quote proof
   246   fix n :: nat
   246   fix n :: nat
   247   show "\<one> \<otimes> n = n"
   247   show "\<one> \<otimes> n = n"
   248     unfolding neutral_nat_def by simp
   248     unfolding neutral_nat_def by simp
   259 
   259 
   260 definition %quote
   260 definition %quote
   261   neutral_prod_def: "\<one> = (\<one>, \<one>)"
   261   neutral_prod_def: "\<one> = (\<one>, \<one>)"
   262 
   262 
   263 instance %quote proof
   263 instance %quote proof
   264   fix p :: "\<alpha>\<Colon>monoidl \<times> \<beta>\<Colon>monoidl"
   264   fix p :: "\<alpha>::monoidl \<times> \<beta>::monoidl"
   265   show "\<one> \<otimes> p = p"
   265   show "\<one> \<otimes> p = p"
   266     unfolding neutral_prod_def mult_prod_def by (simp add: neutl)
   266     unfolding neutral_prod_def mult_prod_def by (simp add: neutl)
   267 qed
   267 qed
   268 
   268 
   269 end %quote
   269 end %quote
   293 
   293 
   294 instantiation %quote prod :: (monoid, monoid) monoid
   294 instantiation %quote prod :: (monoid, monoid) monoid
   295 begin
   295 begin
   296 
   296 
   297 instance %quote proof 
   297 instance %quote proof 
   298   fix p :: "\<alpha>\<Colon>monoid \<times> \<beta>\<Colon>monoid"
   298   fix p :: "\<alpha>::monoid \<times> \<beta>::monoid"
   299   show "p \<otimes> \<one> = p"
   299   show "p \<otimes> \<one> = p"
   300     unfolding neutral_prod_def mult_prod_def by (simp add: neutr)
   300     unfolding neutral_prod_def mult_prod_def by (simp add: neutr)
   301 qed
   301 qed
   302 
   302 
   303 end %quote
   303 end %quote
   313 
   313 
   314 instantiation %quote int :: group
   314 instantiation %quote int :: group
   315 begin
   315 begin
   316 
   316 
   317 definition %quote
   317 definition %quote
   318   inverse_int_def: "i\<div> = - (i\<Colon>int)"
   318   inverse_int_def: "i\<div> = - (i::int)"
   319 
   319 
   320 instance %quote proof
   320 instance %quote proof
   321   fix i :: int
   321   fix i :: int
   322   have "-i + i = 0" by simp
   322   have "-i + i = 0" by simp
   323   then show "i\<div> \<otimes> i = \<one>"
   323   then show "i\<div> \<otimes> i = \<one>"
   359   primitive type class @{text "idem"}, together with a corresponding
   359   primitive type class @{text "idem"}, together with a corresponding
   360   interpretation:
   360   interpretation:
   361 *}
   361 *}
   362 
   362 
   363 interpretation %quote idem_class:
   363 interpretation %quote idem_class:
   364   idem "f \<Colon> (\<alpha>\<Colon>idem) \<Rightarrow> \<alpha>"
   364   idem "f :: (\<alpha>::idem) \<Rightarrow> \<alpha>"
   365 (*<*)sorry(*>*)
   365 (*<*)sorry(*>*)
   366 
   366 
   367 text {*
   367 text {*
   368   \noindent This gives you the full power of the Isabelle module system;
   368   \noindent This gives you the full power of the Isabelle module system;
   369   conclusions in locale @{text idem} are implicitly propagated
   369   conclusions in locale @{text idem} are implicitly propagated
   392 
   392 
   393 text {*
   393 text {*
   394   \noindent Here the \qt{@{keyword "in"} @{class group}} target
   394   \noindent Here the \qt{@{keyword "in"} @{class group}} target
   395   specification indicates that the result is recorded within that
   395   specification indicates that the result is recorded within that
   396   context for later use.  This local theorem is also lifted to the
   396   context for later use.  This local theorem is also lifted to the
   397   global one @{fact "group.left_cancel:"} @{prop [source] "\<And>x y z \<Colon>
   397   global one @{fact "group.left_cancel:"} @{prop [source] "\<And>x y z ::
   398   \<alpha>\<Colon>group. x \<otimes> y = x \<otimes> z \<longleftrightarrow> y = z"}.  Since type @{text "int"} has been
   398   \<alpha>::group. x \<otimes> y = x \<otimes> z \<longleftrightarrow> y = z"}.  Since type @{text "int"} has been
   399   made an instance of @{text "group"} before, we may refer to that
   399   made an instance of @{text "group"} before, we may refer to that
   400   fact as well: @{prop [source] "\<And>x y z \<Colon> int. x \<otimes> y = x \<otimes> z \<longleftrightarrow> y =
   400   fact as well: @{prop [source] "\<And>x y z :: int. x \<otimes> y = x \<otimes> z \<longleftrightarrow> y =
   401   z"}.
   401   z"}.
   402 *}
   402 *}
   403 
   403 
   404 
   404 
   405 subsection {* Derived definitions *}
   405 subsection {* Derived definitions *}
   413   | "pow_nat (Suc n) x = x \<otimes> pow_nat n x"
   413   | "pow_nat (Suc n) x = x \<otimes> pow_nat n x"
   414 
   414 
   415 text {*
   415 text {*
   416   \noindent If the locale @{text group} is also a class, this local
   416   \noindent If the locale @{text group} is also a class, this local
   417   definition is propagated onto a global definition of @{term [source]
   417   definition is propagated onto a global definition of @{term [source]
   418   "pow_nat \<Colon> nat \<Rightarrow> \<alpha>\<Colon>monoid \<Rightarrow> \<alpha>\<Colon>monoid"} with corresponding theorems
   418   "pow_nat :: nat \<Rightarrow> \<alpha>::monoid \<Rightarrow> \<alpha>::monoid"} with corresponding theorems
   419 
   419 
   420   @{thm pow_nat.simps [no_vars]}.
   420   @{thm pow_nat.simps [no_vars]}.
   421 
   421 
   422   \noindent As you can see from this example, for local definitions
   422   \noindent As you can see from this example, for local definitions
   423   you may use any specification tool which works together with
   423   you may use any specification tool which works together with
   540   "pow_int k x = (if k >= 0
   540   "pow_int k x = (if k >= 0
   541     then pow_nat (nat k) x
   541     then pow_nat (nat k) x
   542     else (pow_nat (nat (- k)) x)\<div>)"
   542     else (pow_nat (nat (- k)) x)\<div>)"
   543 
   543 
   544 text {*
   544 text {*
   545   \noindent yields the global definition of @{term [source] "pow_int \<Colon>
   545   \noindent yields the global definition of @{term [source] "pow_int ::
   546   int \<Rightarrow> \<alpha>\<Colon>group \<Rightarrow> \<alpha>\<Colon>group"} with the corresponding theorem @{thm
   546   int \<Rightarrow> \<alpha>::group \<Rightarrow> \<alpha>::group"} with the corresponding theorem @{thm
   547   pow_int_def [no_vars]}.
   547   pow_int_def [no_vars]}.
   548 *}
   548 *}
   549 
   549 
   550 subsection {* A note on syntax *}
   550 subsection {* A note on syntax *}
   551 
   551 
   557 
   557 
   558 context %quote semigroup
   558 context %quote semigroup
   559 begin
   559 begin
   560 
   560 
   561 term %quote "x \<otimes> y" -- {* example 1 *}
   561 term %quote "x \<otimes> y" -- {* example 1 *}
   562 term %quote "(x\<Colon>nat) \<otimes> y" -- {* example 2 *}
   562 term %quote "(x::nat) \<otimes> y" -- {* example 2 *}
   563 
   563 
   564 end  %quote
   564 end  %quote
   565 
   565 
   566 term %quote "x \<otimes> y" -- {* example 3 *}
   566 term %quote "x \<otimes> y" -- {* example 3 *}
   567 
   567 
   568 text {*
   568 text {*
   569   \noindent Here in example 1, the term refers to the local class
   569   \noindent Here in example 1, the term refers to the local class
   570   operation @{text "mult [\<alpha>]"}, whereas in example 2 the type
   570   operation @{text "mult [\<alpha>]"}, whereas in example 2 the type
   571   constraint enforces the global class operation @{text "mult [nat]"}.
   571   constraint enforces the global class operation @{text "mult [nat]"}.
   572   In the global context in example 3, the reference is to the
   572   In the global context in example 3, the reference is to the
   573   polymorphic global class operation @{text "mult [?\<alpha> \<Colon> semigroup]"}.
   573   polymorphic global class operation @{text "mult [?\<alpha> :: semigroup]"}.
   574 *}
   574 *}
   575 
   575 
   576 section {* Further issues *}
   576 section {* Further issues *}
   577 
   577 
   578 subsection {* Type classes and code generation *}
   578 subsection {* Type classes and code generation *}