My Technical Notes

Wednesday, 11 June 2014

Embedding F# In PowerShell

Following on from Doug Finke's ‘Embedding’ F# in PowerShell article, I wanted to load F# scripts within PowerShell.

Later, after a bit of Google-ing, I worked out that you don't need to use the fsc.exe compiler, because we can instead use Add-Type. However we need a "CodeDom" for the F#. I ended up installing The Old F# "PowerPack", which includes one in its FSharp.Compiler.CodeDom.dll DLL file.

Here is the definition of my Add-FSharpType CmdLet:

Add-Type -Path 'C:\Program Files (x86)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\\FSharp.Core.dll'
Add-Type -Path 'C:\Program Files (x86)\FSharpPowerPack-\bin\FSharp.Compiler.CodeDom.dll'

Function Add-FSharpType([string]$Path=$null, [string]$TypeDefinition=$null) {
    if ( (-not $Path) -and (-not $TypeDefinition) ) {
        Write-Host '***** Path or TypeDefinition must be given ****' -ForegroundColor 'Red'
    } else {
        $FSharpCodeProvider = New-Object Microsoft.FSharp.Compiler.CodeDom.FSharpCodeProvider
        $FSharpCode = if ($Path) { [System.IO.File]::ReadAllText($Path) } else { $TypeDefinition }
        Add-Type -TypeDefinition $FSharpCode -CodeDomProvider $FSharpCodeProvider

Give either of these two parameters:

  • Path - the path to the F# script file.
  • TypeDefinition - a string containing the F# code.

#example of calling -Path:
Add-FSharpType -Path 'C:\Path\to\fib.fs'

#example of calling -TypeDefinition
$fibCode = @"
module Strangelights.Fibonacci
let fibs =
    (1,1) |> Seq.unfold
        (fun (n0,n1) ->
            Some(n0, (n1, n0 + n1)))
let get n =
    Seq.nth n fibs
Add-FSharpType -TypeDefinition $fibCode
To invoke the Fibonacci code:

> [Strangelights.Fibonacci]::get(5)


Sergey Tihon said...

Have you tried F# Compiler Services?

Tahir Hassan said...

Sergey (sorry for the late reply), I remember trying it, but I just couldn't get it to work.