I wasn’t sure I was going to report a version of Y using Object rather than explicit recursive types, but it turned out to be so easy and pretty that I couldn’t resist. It’s rather a dead-end, evolutionarily speaking, since future development will use the template of the explicit Universal type presented last time, but it’s amusing enough for a blog entry:
REM (λ a -> z z a)
Class OfA
Private Z As Object
Sub New(ByVal Z As Object)
Me.Z = Z
End Sub
Function [Of](ByVal a As Object) As Object
Return Z.[Of](Z).[Of](a)
End Function
End Class
REM [λ z -> h(λ a -> z z a)]
Class OfZ
Private H As Object
Sub New(ByVal H As Object)
Me.H = H
End Sub
Function [Of](ByVal z As Object) As Object
Return H.[Of](New OfA(z))
End Function
End Class
REM y h = [λ z -> h(λ a -> z z a)] [λ z -> h(λ a -> z z a)]
Class Y
Function [Of](ByVal h As Object) As Object
Dim z As New OfZ(h)
Return z.[Of](z)
End Function
End Class
REM λ n -> if n=0 return 1 else return n * fact(n - 1)
Class OfN
Private fact As Object
Sub New(ByVal h As Object) REM inflate the closure
Me.fact = h
End Sub
Function [Of](ByVal N As Object) As Object
If N < 0 Then
Return N
End If
If N = 0 Then
Return 1
Else
Return N * fact.[Of](N - 1)
End If
End Function
End Class
REM Currying: λ g -> (λ n -> ...). This is our target for y.
Class f
Function [Of](ByVal fact As Object) As Object
Return New OfN(fact)
End Function
End Class
Module Module1
Sub Main()
Dim y = New Y()
Dim fact = y.[Of](New f)
Dim result As Object = 1
While result > 0
Console.Write("Enter an Integer Number (negative to stop): ")
result = fact.[Of](Console.ReadLine())
Console.WriteLine("{0}", result)
End While
End Sub
End Module