Skip to content

Commit b848cc4

Browse files
committed
Added a Cloner interface for FunctionType and Record
1 parent 8c3004b commit b848cc4

File tree

4 files changed

+50
-1
lines changed

4 files changed

+50
-1
lines changed

functionType.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,21 @@ func (t *FunctionType) FlatTypes() Types {
104104
}
105105
return retVal
106106
}
107+
108+
// Clone implements Cloner
109+
func (t *FunctionType) Clone() interface{} {
110+
retVal := new(FunctionType)
111+
112+
if ac, ok := t.a.(Cloner); ok {
113+
retVal.a = ac.Clone().(Type)
114+
} else {
115+
retVal.a = t.a
116+
}
117+
118+
if bc, ok := t.b.(Cloner); ok {
119+
retVal.b = bc.Clone().(Type)
120+
} else {
121+
retVal.b = t.b
122+
}
123+
return retVal
124+
}

functionType_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,12 @@ func TestFunctionType_FlatTypes(t *testing.T) {
8787
ts = fnType2.FlatTypes()
8888
assert.Equal(t, ts, correct)
8989
}
90+
91+
func TestFunctionType_Clone(t *testing.T) {
92+
fnType := NewFnType(TypeVariable('a'), TypeVariable('b'), TypeVariable('c'))
93+
assert.Equal(t, fnType.Clone(), fnType)
94+
95+
rec := NewRecordType("", TypeVariable('a'), NewFnType(TypeVariable('a'), TypeVariable('b')), TypeVariable('c'))
96+
fnType = NewFnType(rec, rec)
97+
assert.Equal(t, fnType.Clone(), fnType)
98+
}

hm.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ package hm
22

33
import "github.com/pkg/errors"
44

5+
// Cloner is any type that can clone
6+
type Cloner interface {
7+
Clone() interface{}
8+
}
9+
510
// Fresher keeps track of all the TypeVariables that has been generated so far. It has one method - Fresh(), which is to create a new TypeVariable
611
type Fresher interface {
712
Fresh() TypeVariable

type.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ type Substitutable interface {
2222
FreeTypeVar() TypeVarSet
2323
}
2424

25-
// TypeConst are the default implementation of a constant type. Feel free to implement your own
25+
// TypeConst are the default implementation of a constant type. Feel free to implement your own. TypeConsts should be immutable (so no pointer types plz)
2626
type TypeConst string
2727

2828
func (t TypeConst) Name() string { return string(t) }
@@ -116,3 +116,20 @@ func (t *Record) Format(f fmt.State, c rune) {
116116
}
117117

118118
func (t *Record) String() string { return fmt.Sprintf("%v", t) }
119+
120+
// Clone implements Cloner
121+
func (t *Record) Clone() interface{} {
122+
retVal := new(Record)
123+
ts := BorrowTypes(len(t.ts))
124+
for i, tt := range t.ts {
125+
if c, ok := tt.(Cloner); ok {
126+
ts[i] = c.Clone().(Type)
127+
} else {
128+
ts[i] = tt
129+
}
130+
}
131+
retVal.ts = ts
132+
retVal.name = t.name
133+
134+
return retVal
135+
}

0 commit comments

Comments
 (0)