mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
Fix #5084
This commit is contained in:
committed by
Andreas Rumpf
parent
7db883e4d3
commit
90e82f8ecf
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
61
tests/concepts/trandomvars.nim
Normal file
61
tests/concepts/trandomvars.nim
Normal file
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user