14.11.2012 Views

Curry: An Integrated Functional Logic Language

Curry: An Integrated Functional Logic Language

Curry: An Integrated Functional Logic Language

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

and introduces a new n-ary type constructor T and k new (data) constructors C1, . . . , Ck, where<br />

each Ci has the type<br />

τi1 -> · · · -> τini -> T α1 . . . αn<br />

(i = 1, . . . , k). Each τij is a type expression built from the type variables α1, . . . , αn and some<br />

type constructors. <strong>Curry</strong> has a number of built-in type constructors, like Bool, Int, -> (function<br />

space), or, lists and tuples, which are described in Section 4.1. Since <strong>Curry</strong> is a higher-order<br />

language, the types of functions (i.e., constructors or operations) are written in their curried form<br />

τ1 -> τ2 -> · · · -> τn -> τ where τ is not a functional type. In this case, n is called the arity of<br />

the function. For instance, the datatype declarations<br />

data Bool = True | False<br />

data List a = [] | a : List a<br />

data Tree a = Leaf a | Node (Tree a) a (Tree a)<br />

introduces the datatype Bool with the 0-ary constructors (constants) True and False, and the<br />

polymorphic types List a and Tree a of lists and binary trees. Here, “:” is an infix operator, i.e.,<br />

“a:List a” is another notation for “(:) a (List a)”. Lists are predefined in <strong>Curry</strong>, where the<br />

notation “[a]” is used to denote list types (instead of “List a”). The usual convenient notations<br />

for lists are supported, i.e., [0,1,2] is an abbreviation for 0:(1:(2:[])) (see also Section 4.1).<br />

A data term is a variable x or a constructor application c t1 . . . tn where c is an n-ary constructor<br />

and t1, . . . , tn are data terms. <strong>An</strong> expression is a variable or a (partial) application ϕ e1 . . . em<br />

where ϕ is a function or constructor and e1, . . . , em are expressions. A data term or expression is<br />

called ground if it does not contain any variable. Ground data terms correspond to values in the<br />

intended domain, and expressions containing operations should be evaluated to data terms. Note<br />

that traditional functional languages compute on ground expressions, whereas logic languages also<br />

allow non-ground expressions.<br />

2.2 Type Synonym Declarations<br />

To make type definitions more readable, it is possible to specify new names for type expressions by<br />

a type synonym declaration. Such a declaration has the general form<br />

type T α1 ... αn = τ<br />

which introduces a new n-ary type constructor T . α1, . . . , αn are pairwise distinct type variables<br />

and τ is a type expressions built from type constructors and the type variables α1, . . . , αn. The type<br />

(T τ1 . . . τn) is equivalent to the type {α1 ↦→ τ1, . . . , αn ↦→ τn}(τ), i.e., the type expression τ where<br />

each αi is replaced by τi. Thus, a type synonym and its definition are always interchangeable and<br />

have no influence on the typing of a program. For example, we can provide an alternative notation<br />

for list types and strings by the following type synonym declarations:<br />

type List a = [a]<br />

type Name = [Char]<br />

Since a type synonym introduces just another name for a type expression, recursive or mutually<br />

dependent type synonym declarations are not allowed. Therefore, the following declarations are<br />

invalid:<br />

4

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!