<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <HTML ><HEAD ><TITLE >Implicit parameters</TITLE ><META NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK REL="HOME" TITLE="The Hugs 98 User's Guide" HREF="index.html"><LINK REL="UP" TITLE="Language extensions supported by Hugs and GHC" HREF="hugs-ghc.html"><LINK REL="PREVIOUS" TITLE="Type annotations in patterns" HREF="type-annotations.html"><LINK REL="NEXT" TITLE="Hugs-specific language extensions" HREF="hugs-only.html"><LINK REL="STYLESHEET" TYPE="text/css" HREF="hugs-ug.css"></HEAD ><BODY CLASS="SECT1" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#840084" ALINK="#0000FF" ><DIV CLASS="NAVHEADER" ><TABLE SUMMARY="Header navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TH COLSPAN="3" ALIGN="center" >The Hugs 98 User's Guide</TH ></TR ><TR ><TD WIDTH="10%" ALIGN="left" VALIGN="bottom" ><A HREF="type-annotations.html" ACCESSKEY="P" >Prev</A ></TD ><TD WIDTH="80%" ALIGN="center" VALIGN="bottom" >Chapter 6. Language extensions supported by Hugs and GHC</TD ><TD WIDTH="10%" ALIGN="right" VALIGN="bottom" ><A HREF="hugs-only.html" ACCESSKEY="N" >Next</A ></TD ></TR ></TABLE ><HR ALIGN="LEFT" WIDTH="100%"></DIV ><DIV CLASS="SECT1" ><H1 CLASS="SECT1" ><A NAME="IMPLICIT-PARAMETERS" >6.5. Implicit parameters</A ></H1 ><P > Implicit parameters are implemented as described in <I CLASS="CITETITLE" >Implicit parameters: dynamic scoping with static types</I >, J Lewis, MB Shields, E Meijer, J Launchbury, <I CLASS="CITETITLE" >27th ACM Symposium on Principles of Programming Languages (POPL'00)</I >, Boston, Jan 2000. Note however that the binding syntax in that paper, using keywords <TT CLASS="LITERAL" >dlet</TT > and <TT CLASS="LITERAL" >with</TT >, has been replaced by the form presented below.</P ><P >(Most of the following, still rather incomplete, documentation is due to Jeff Lewis.)</P ><P >A variable is called <I CLASS="FIRSTTERM" >dynamically bound</I > when it is bound by the calling context of a function and <I CLASS="FIRSTTERM" >statically bound</I > when bound by the callee's context. In Haskell, all variables are statically bound. Dynamic binding of variables is a notion that goes back to Lisp, but was later discarded in more modern incarnations, such as Scheme, as dynamic binding can be very confusing in an untyped language. Unfortunately typed languages, in particular Hindley-Milner typed languages like Haskell, only support static scoping of variables.</P ><P >However, by a simple extension to the type class system of Haskell, we can support dynamic binding. Basically, we express the use of a dynamically bound variable as a constraint on the type. These constraints lead to types of the form <TT CLASS="LITERAL" >(?x::t') => t</TT >, which says <SPAN CLASS="QUOTE" >"this function uses a dynamically-bound variable <TT CLASS="LITERAL" >?x</TT > of type <TT CLASS="LITERAL" >t'</TT >"</SPAN >. For example, the following expresses the type of a <CODE CLASS="FUNCTION" >sort</CODE > function, implicitly parameterized by a comparison function named <TT CLASS="LITERAL" >cmp</TT >. <PRE CLASS="PROGRAMLISTING" >sort :: (?cmp :: a -> a -> Bool) => [a] -> [a]</PRE > The dynamic binding constraints are just a new form of predicate in the type class system.</P ><P >An implicit parameter occurs in an expression using the special form <TT CLASS="LITERAL" >?x</TT >, where <TT CLASS="LITERAL" >x</TT > is any valid identifier (e.g. <TT CLASS="LITERAL" >ord ?x</TT > is a valid expression). Use of this construct also introduces a new dynamic-binding constraint in the type of the expression. For example, the following definition shows how we can define an implicitly parameterized sort function in terms of an explicitly parameterized <CODE CLASS="FUNCTION" >sortBy</CODE > function: <PRE CLASS="PROGRAMLISTING" >sortBy :: (a -> a -> Bool) -> [a] -> [a] sort :: (?cmp :: a -> a -> Bool) => [a] -> [a] sort = sortBy ?cmp</PRE ></P ><DIV CLASS="SECT2" ><H2 CLASS="SECT2" ><A NAME="AEN1588" >6.5.1. Implicit-parameter type constraints</A ></H2 ><P >Dynamic binding constraints behave just like other type class constraints in that they are automatically propagated. Thus, when a function is used, its implicit parameters are inherited by the function that called it. For example, our <CODE CLASS="FUNCTION" >sort</CODE > function might be used to pick out the least value in a list: <PRE CLASS="PROGRAMLISTING" >least :: (?cmp :: a -> a -> Bool) => [a] -> a least xs = fst (sort xs)</PRE > Without lifting a finger, the <TT CLASS="LITERAL" >?cmp</TT > parameter is propagated to become a parameter of <CODE CLASS="FUNCTION" >least</CODE > as well. With explicit parameters, the default is that parameters must always be explicitly propagated. With implicit parameters, the default is to always propagate them.</P ><P >An implicit-parameter type constraint differs from other type class constraints in the following way: all uses of a particular implicit parameter must have the same type. This means that the type of <TT CLASS="LITERAL" >(?x, ?x)</TT > is <TT CLASS="LITERAL" >(?x::a) => (a,a)</TT >, and not <TT CLASS="LITERAL" >(?x::a, ?x::b) => (a, b)</TT >, as would be the case for type class constraints.</P ><P >You can't have an implicit parameter in the context of a class or instance declaration. For example, both these declarations are illegal: <PRE CLASS="PROGRAMLISTING" >class (?x::Int) => C a where ... instance (?x::a) => Foo [a] where ...</PRE > Reason: exactly which implicit parameter you pick up depends on exactly where you invoke a function. But the <SPAN CLASS="QUOTE" >"invocation"</SPAN > of instance declarations is done behind the scenes by the compiler, so it's hard to figure out exactly where it is done. The easiest thing is to outlaw the offending types.</P ><P >Implicit-parameter constraints do not cause ambiguity. For example, consider: <PRE CLASS="PROGRAMLISTING" >f :: (?x :: [a]) => Int -> Int f n = n + length ?x g :: (Read a, Show a) => String -> String g s = show (read s)</PRE > Here, <TT CLASS="LITERAL" >g</TT > has an ambiguous type, and is rejected, but <TT CLASS="LITERAL" >f</TT > is fine. The binding for <TT CLASS="LITERAL" >?x</TT > at <TT CLASS="LITERAL" >f</TT >'s call site is quite unambiguous, and fixes the type <TT CLASS="LITERAL" >a</TT >.</P ></DIV ><DIV CLASS="SECT2" ><H2 CLASS="SECT2" ><A NAME="AEN1609" >6.5.2. Implicit-parameter bindings</A ></H2 ><P >An implicit parameter is <I CLASS="FIRSTTERM" >bound</I > using the standard <TT CLASS="LITERAL" >let</TT > or <TT CLASS="LITERAL" >where</TT > binding forms. For example, we define the <CODE CLASS="FUNCTION" >min</CODE > function by binding <TT CLASS="LITERAL" >cmp</TT >: <PRE CLASS="PROGRAMLISTING" >min :: [a] -> a min = let ?cmp = (<=) in least</PRE ></P ><P >A group of implicit-parameter bindings may occur anywhere a normal group of Haskell bindings can occur, except at top level. That is, they can occur in a <TT CLASS="LITERAL" >let</TT > (including in a list comprehension or do-notation), or a <TT CLASS="LITERAL" >where</TT > clause. Note the following points: <P ></P ><UL ><LI ><P >An implicit-parameter binding group must be a collection of simple bindings to implicit-style variables (no function-style bindings, and no type signatures); these bindings are neither polymorphic or recursive.</P ></LI ><LI ><P >You may not mix implicit-parameter bindings with ordinary bindings in a single <TT CLASS="LITERAL" >let</TT > expression; use two nested <TT CLASS="LITERAL" >let</TT >s instead. (In the case of <TT CLASS="LITERAL" >where</TT > you are stuck, since you can't nest <TT CLASS="LITERAL" >where</TT > clauses.)</P ></LI ><LI ><P >You may put multiple implicit-parameter bindings in a single binding group; but they are <SPAN CLASS="emphasis" ><I CLASS="EMPHASIS" >not</I ></SPAN > treated as a mutually recursive group (as ordinary <TT CLASS="LITERAL" >let</TT > bindings are). Instead they are treated as a non-recursive group, simultaneously binding all the implicit parameters. The bindings are not nested, and may be re-ordered without changing the meaning of the program. For example, consider: <PRE CLASS="PROGRAMLISTING" >f t = let { ?x = t; ?y = ?x+(1::Int) } in ?x + ?y</PRE > The use of <TT CLASS="LITERAL" >?x</TT > in the binding for <TT CLASS="LITERAL" >?y</TT > does not <SPAN CLASS="QUOTE" >"see"</SPAN > the binding for <TT CLASS="LITERAL" >?x</TT >, so the type of <TT CLASS="LITERAL" >f</TT > is <PRE CLASS="SCREEN" >f :: (?x::Int) => Int -> Int</PRE ></P ></LI ></UL ></P ></DIV ></DIV ><DIV CLASS="NAVFOOTER" ><HR ALIGN="LEFT" WIDTH="100%"><TABLE SUMMARY="Footer navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" ><A HREF="type-annotations.html" ACCESSKEY="P" >Prev</A ></TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="index.html" ACCESSKEY="H" >Home</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" ><A HREF="hugs-only.html" ACCESSKEY="N" >Next</A ></TD ></TR ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" >Type annotations in patterns</TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="hugs-ghc.html" ACCESSKEY="U" >Up</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" >Hugs-specific language extensions</TD ></TR ></TABLE ></DIV ></BODY ></HTML >