The proc needs to return a concrete type, while you're trying to return 
Something, which is a type class. You'll be better here with either runtime 
dispatch (`ref object` hierarchy + `methods`) or variant objects. 
    
    
    # runtime dispatch
    type
      Something = object
        a: int
        special: Special
      
      Special = ref object {.inheritable.}
      SpecialisedTA = ref object of Special
        c: int
      SpecialisedTB = ref object of Special
        d: int
    
    method foo(s: Special) {.base.} = assert(false, "Kinda abstract")
    method foo(s: SpecialisedTA) = echo "SpecialisedTA"
    method foo(s: SpecialisedTB) = echo "SpecialisedTB"
    
    proc doIt(strategy: int): Something =
      if (...):
        result = Something(a: 10, special: SpecialisedTA(c: 30))
      else:
        result = Something(a: 10, special: SpecialisedTB(d: 10))
    
    let myThing = doIt(...)
    myThing.special.foo()
    
    
    Run
    
    
    # variant object
    type
      SpecialKind = enum
        TA
        TB
      
      Something = object
        a: int
        case kind
        of TA:
          specialA: SpecialisedTA
        of TB:
          specialB: SpecialisedTB
      
      SpecialisedTA = object
         c: int
      
      SpecialisedTB = object
         d: int
    
    proc doIt(strategy: int): Something =
      if (...):
        result = Something(a: 10, kind: TA, specialA: SpecialisedTA(c: 30))
      else:
        result = Something(a: 10, kind: TB, specialB: SpecialisedTB(d: 10))
    
    let myThing = doIt(...)
    case myThing.kind
    of TA:
      echo "SpecialA: ", myThing.specialA
    of TB:
      echo "SpecialB: ", myThing.specialB
    
    
    Run

Reply via email to