I have the following discriminated union type:
type Value =
| Float of float
| Int of int
| String of string
| Function of (ContextStack -> Value -> Value)
| Action of (unit -> Value)
| Constructor of string * int * Value
| Type of string * Context
| Object of Value * List<Value>
| Ref of Context * (Context -> Value) * (Context -> Value -> Context)
| Unrecognizable of Node
| Closure of Value * ContextStack * bool
| Application of Value * Value
where some constructors contain a field of type Context
, which is basically just a System.Collections.Generic.Dictionary<string, Value>
(and ContextStack
is Context list
). Because of that, there can be a situation, when a Value
instance contains a reference to a dictionary, that contains said instance. Trying to print it using sprintf "%A"
, that recursively traverses the object, will result in unending recursion and StackOverflow
error. But it is not really a problem for the application itself - as I never print these values anyway. However, when I am trying to debug my program, debugger tries to evaluate all object's string representation and fails with stack overflow.
To solve it, I tried to override ToString
method, thinking the debugger uses it for string representation, but it didn't work. Even this:
type Value =
| Float of float
| Int of int
| String of string
| Function of (ContextStack -> Value -> Value)
| Action of (unit -> Value)
| Constructor of string * int * Value
| Type of string * Context
| Object of Value * List<Value>
| Ref of Context * (Context -> Value) * (Context -> Value -> Context)
| Unrecognizable of Node
| Closure of Value * ContextStack * bool
| Application of Value * Value
with override this.ToString(): string = "Please, don't crash!"
causes an error. What do I do?
Just in case:
Update: it seems that debugger actually uses toString
for string representation, but only if the object to represent is Value
. Trying to sprintf "%A"
dictionary, that contains Value
object, will call sprintf "%A"
on the contained Value
object instead of its toString
.
It turns out, there is a debugger option to disable implicit evaluation. In Rider. it is: Settings -> Build, Execution, Deployment -> Debugger -> Value inspections/Allow property evaluations and other implicit function calls
. Disabling this option solves the issue.