12

If one uses the F# Interactive Shell (FSI), the inferred expression type (signature) is printed to the console along with its value:

val it : int * string * float = (42, "Hello F#", 42.0)

How can I mimick the same behaviour in my own code, e.g. to get the inferred types as string for a F# expression?

I don't need to dynamically evaluate any F# expressions, the expressions are known in compile time and are part of my (static) F# code. I need this feature to be able to mimick the FSI output in LINQPad for my F# demos.

p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
Alexander Galkin
  • 12,086
  • 12
  • 63
  • 115
  • If the expressions are known ahead-of-time, why not run them through FSI ahead-of-time as well? – pblasucci Mar 28 '12 at 16:23
  • @pblasucci I use LinqPAD for live coding and it works perfectly well with F#. Switching to FSI every time I need to show a signature for an expression would be too much time waste. But I keep it as an option, thanks! – Alexander Galkin Mar 28 '12 at 18:53
  • @AlexanderGalkin Can LinqPAD execute a shell command? You could shell out and run the fsc command with the --sig flag and pass it the file you're currently working on. – Onorio Catenacci Mar 28 '12 at 19:07
  • @OnorioCatenacci Yes, that would be a solution too. But for demo purposes it is much easier just to type the signature manually -- I just wanted to show how to read these signatures to F# beginners and looked for a quick solution which doesn't seem to exist. – Alexander Galkin Mar 29 '12 at 07:34
  • I don't think I understand the scenario, so maybe this isn't relevant, but anyway: If you activate the premium features of LINQPad, mousing over source will show the type info. – Bent Tranberg Feb 01 '22 at 14:24

2 Answers2

11

Using Unquote

Unquote has a facility for getting the F# signature of a type. Simply download the latest release and add a reference through LINQPad to Unquote.dll, then you can do e.g.

enter image description here

If you're interested, you can peak at the source code for the implementation of the FSharpName Type extension: https://github.com/SwensenSoftware/unquote/blob/2.1.0/Unquote/ExtraReflection.fs#L54

Using FsEye

Another neat approach would be to use LINQPad's beta Custom Visualizer API to embed FsEye into LINQPad (FsEye uses the same F# type signature printing algorithm as Unquote). This is also very simple, all you need to do is download LINQPad beta, download and reference FsEye.dll from the latest release of FsEye, then you can do e.g.

enter image description here

farlee2121
  • 2,959
  • 4
  • 29
  • 41
Stephen Swensen
  • 22,107
  • 9
  • 81
  • 136
  • I **love** those environment mixing data and metadata. I would equally love them right within visual studio, doing expression replacement to have concrete results of functions we are writing... – nicolas Apr 29 '12 at 12:18
  • 1
    Rather than download and ref a dll manually, since LinqPad beta supports nuget packages, maybe a nuget package of the FsEye dll? – jbtule Mar 21 '14 at 13:42
  • Good suggestion @jbtule. I've had in mind to create an FsEye NuGet package for some time. Scenarios like this are good motivation. I actually already have an issue written for this (different motivation, but same ends): https://code.google.com/p/fseye/issues/detail?id=30 – Stephen Swensen Mar 21 '14 at 15:32
  • Hi, unfortunately, the unquote solution seems no longer to work (at least for me). I tried the following code snippet: type Test()=member public this.s2()="Hello" let x=new Test() x.GetType().FSharpName returns a string and Dump does not exist. – Andreas Morgenstern Aug 26 '14 at 12:14
  • @AndreasMorgenstern I've got to imagine you are experiencing a user error: `Dump()` is an extension method LinqPAD provides for all `Object` types. If it "doesn't exist", that is problem above Unquote. Perhaps post a question with precise repo steps to get better help. – Stephen Swensen Aug 26 '14 at 14:19
1

If you look at the F# compiler code and see how the --sig option is handled by the compiler I think that will get you what you're looking for. More about the --sig option and signatures here:

Signatures (F#)

Onorio Catenacci
  • 14,928
  • 14
  • 81
  • 132
  • Thank you for your suggestion -- I added the signatures to my question. Trying to delve into the compiler implementation seems like an overkill for me, sorry. – Alexander Galkin Mar 28 '12 at 13:43
  • Why not just use the `--sig` option and present the signature file during the demos? – Ramon Snir Mar 28 '12 at 17:05
  • I thought he was asking how to do this programmatically. – Onorio Catenacci Mar 28 '12 at 17:10
  • @RamonSnir THe idea is not to show how to generate signatures. Rather, I just want to show some typical functions and explain what they expect and what they return -- running compiler every time to produce a signature is too much work here, it will be easier for me just to write the signature by heart. – Alexander Galkin Mar 28 '12 at 18:55