Skip to content

Commit

Permalink
Fix #5084
Browse files Browse the repository at this point in the history
  • Loading branch information
zah authored and Araq committed Jun 20, 2017
1 parent 7db883e commit 90e82f8
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 3 deletions.
9 changes: 6 additions & 3 deletions compiler/sigmatch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -628,9 +628,9 @@ proc typeRangeRel(f, a: PType): TTypeRelation {.noinline.} =
else:
result = isNone

proc matchUserTypeClass*(c: PContext, m: var TCandidate,
ff, a: PType): PType =
proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType =
var
c = m.c
typeClass = ff.skipTypes({tyUserTypeClassInst})
body = typeClass.n[3]
matchedConceptContext: TMatchedConcept
Expand Down Expand Up @@ -661,6 +661,9 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
typeParamName = ff.base.sons[i-1].sym.name
typ = ff.sons[i]
param: PSym
alreadyBound = PType(idTableGet(m.bindings, typ))

if alreadyBound != nil: typ = alreadyBound

template paramSym(kind): untyped =
newSym(kind, typeParamName, typeClass.sym, typeClass.sym.info)
Expand Down Expand Up @@ -1490,7 +1493,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
else:
considerPreviousT:
if aOrig == f: return isEqual
var matched = matchUserTypeClass(c.c, c, f, aOrig)
var matched = matchUserTypeClass(c, f, aOrig)
if matched != nil:
bindConcreteTypeToUserTypeClass(matched, a)
if doBind: put(c, f, matched)
Expand Down
61 changes: 61 additions & 0 deletions tests/concepts/trandomvars.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
discard """
output: '''
true
true
true
3
18.0
324.0
'''
"""

type RNG = object

proc random(rng: var RNG): float = 1.0

type
RandomVar[A] = concept x
var rng: RNG
rng.sample(x) is A

Constant[A] = object
value: A

Uniform = object
a, b: float

ClosureVar[A] = proc(rng: var RNG): A

proc sample[A](rng: var RNG, c: Constant[A]): A = c.value

proc sample(rng: var RNG, u: Uniform): float = u.a + (u.b - u.a) * rng.random()

proc sample[A](rng: var RNG, c: ClosureVar[A]): A = c(rng)

proc constant[A](a: A): Constant[A] = Constant[A](value: a)

proc uniform(a, b: float): Uniform = Uniform(a: a, b: b)

proc lift1[A, B](f: proc(a: A): B, r: RandomVar[A]): ClosureVar[B] =
proc inner(rng: var RNG): B = f(rng.sample(r))

return inner

when isMainModule:
proc sq(x: float): float = x * x

let
c = constant(3)
u = uniform(2, 18)
t = lift1(sq, u)

var rng: RNG

echo(c is RandomVar[int])
echo(u is RandomVar[float])
echo(t is RandomVar[float])

echo rng.sample(c)
echo rng.sample(u)
echo rng.sample(t)

0 comments on commit 90e82f8

Please sign in to comment.