我有一个 Powershell 脚本,我加载了一个 F# 库并创建了一个 F# 记录表达式:

$teacher = Data+Teacher("Joan", "Doe", 27)

现在我需要将 $teacher 传递给一个函数,但在此之前我需要将它向上转换为类型 SchoolEmployee 。当我尝试:
$schoolEmployee = $teacher -as [Data+SchoolEmployee]

我拿回了一个空物体。在我的 F# 模块中,我有一个可区分的联合:
 module Data =
     type SchoolEmployee =
     | Teacher of Teacher
     | Cleaner of Cleaner

我如何向上转换到 F# 中的 Powershell 区分联合类型?

最佳答案

使用 the related questionTeacher 记录的这个定义:

module People =
    type Teacher = {
        FirstName:string
        LastName:string
        Age:int }

您可以在 PowerShell 中创建一个新的 Teacher 对象,如下所示:
$teacher = New-Object Ploeh.StackOverflow.Q32987498.People+Teacher("Jane", "Doe", 27)

(我希望你能原谅我对命名空间的冗长使用,但这就是我编译 Teacher 类型的方式。)

这个 $teacher 对象是 Teacher 记录类型的一个实例:
PS> $teacher.GetType().FullName
Ploeh.StackOverflow.Q32987498.People+Teacher
Teacher 记录类型与 Teacher 案例构造函数不同。 case 构造函数不是类型;这是一个函数。这就是类型转换不起作用的原因。 People+Teacher 不是 SchoolEmployee 的实例。实际上,People+Teacher 被编译为密封类。

为了将其转换为 SchoolEmployee 值,您需要将其传递给 NewTeacher 方法:
$emp = [Ploeh.StackOverflow.Q32987498.Data+SchoolEmployee]::NewTeacher($teacher)

这个 $emp 对象的类型是 SchoolEmployee :
PS> $emp.GetType().FullName
Ploeh.StackOverflow.Q32987498.Data+SchoolEmployee+Teacher

PowerShell 中的 New-Object 语句等效于在 F# 中编写:
let teacher = { FirstName = "Jane"; LastName = "Doe"; Age = 27 };
NewTeacher 方法调用等效于以下 F# 表达式:
let emp = Teacher teacher

在这里,也许更明显的是 Teacher case 构造函数是一个函数,这也是它在 IL 中被编译为方法的原因。

关于Powershell 转换为 F# 可区分联合,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32987498/

10-11 16:20