001: /**************************************************************************/
002: /* B O S S A */
003: /* A simple imperative object-oriented research language */
004: /* (c) Daniel Bonniot 1999 */
005: /* */
006: /* This program is free software; you can redistribute it and/or modify */
007: /* it under the terms of the GNU General Public License as published by */
008: /* the Free Software Foundation; either version 2 of the License, or */
009: /* (at your option) any later version. */
010: /* */
011: /**************************************************************************/package mlsub.typing;
012:
013: import mlsub.typing.lowlevel.Kind;
014:
015: /**
016: * A functional monotype.
017: */
018: public final class FunType extends Monotype {
019: FunType(FunTypeKind kind, Monotype[] in, Monotype out) {
020: this .in = (in == null ? Monotype.zeroMonotypes : in);
021: this .out = out;
022: this .kind = kind;
023: }
024:
025: public FunType(Monotype[] in, Monotype out) {
026: this (FunTypeKind.get(in == null ? 0 : in.length), in, out);
027: }
028:
029: /**
030: Returns true if this monotype is only made of
031: top-level, rigid type constructors
032: */
033: public boolean isRigid() {
034: return out.isRigid() && Monotype.isRigid(in);
035: }
036:
037: Monotype substitute(java.util.Map map) {
038: return new FunType(Monotype.substitute(map, in), out
039: .substitute(map));
040: }
041:
042: /****************************************************************
043: * Functional types
044: ****************************************************************/
045:
046: /** the list of input Monotypes if this type is functional */
047: public Monotype[] domain() {
048: return in;
049: }
050:
051: /** the return type if this type is functional */
052: public Monotype codomain() {
053: return out;
054: }
055:
056: /****************************************************************
057: * low-level interface
058: ****************************************************************/
059:
060: public int getId() {
061: return mlsub.typing.lowlevel.Engine.INVALID;
062: }
063:
064: public void setId(int value) {
065: throw new Error();
066: }
067:
068: Kind kind;
069:
070: public Kind getKind() {
071: return kind;
072: }
073:
074: public void setKind(Kind value) {
075: throw new Error();
076: }
077:
078: /****************************************************************
079: * Misc.
080: ****************************************************************/
081:
082: public boolean equals(Object o) {
083: if (!(o instanceof FunType))
084: return false;
085: FunType that = (FunType) o;
086:
087: return out.equals(that.out) && in.equals(that.in);
088: }
089:
090: public String toString() {
091: return toString(false, null);
092: }
093:
094: public String toString(boolean isNull, String suffix) {
095: StringBuffer res = new StringBuffer();
096: // If there is a suffix, use parenthesis to disambiguate.
097: if (suffix != null)
098: res.append('(');
099: res.append('(').append(bossa.util.Util.map("", ", ", "", in))
100: .append(')');
101: if (isNull)
102: res.append('?');
103: res.append("->").append(out);
104: if (suffix != null)
105: res.append(')').append(suffix);
106: return res.toString();
107: }
108:
109: private Monotype[] in;
110: private Monotype out;
111:
112: /****************************************************************
113: * Simplification
114: ****************************************************************/
115:
116: void tag(int variance) {
117: out.tag(variance);
118: Monotype.tag(in, -1 * variance);
119: }
120:
121: Monotype canonify() {
122: out = out.canonify();
123: in = Monotype.canonify(in);
124: return this;
125: }
126: }
|