0

The following datatype defined in Haskell is:

type Tag = String
type Content = String
data HTML = B Tag Content | R Tag HTML

But in VB.Net i can't define recursive structures. And i don't know how to define the "|" that is a some kind of "or"/"union" in Haskell.

duplode
  • 33,731
  • 7
  • 79
  • 150
lsalvatore
  • 101
  • 1
  • 11
  • Closely related: [*How can I simulate Haskell's “Either a b” in Java*](http://stackoverflow.com/q/9975836/2751851) – duplode Dec 07 '16 at 16:37
  • Why can't you define recursive structures? From a few seconds Googling that looks [pretty trivial](https://www.codeproject.com/articles/4647/a-simple-binary-tree-implementation-with-vb-net) to me. – Daniel Wagner Dec 07 '16 at 17:09
  • Your `Tag` type isn't actually used in your example. – chepner Dec 07 '16 at 17:30
  • `HTML` doesn't have a valid definition; you reuse the `Tag` data constructor. It's also not very interesting; it doesn't define a tree of `Content`, it just allows you to wrap a `Content` value in an arbitrary number of wrappers. As such, it's isomorphic to `type HTML' = (Int, Content)`. – chepner Dec 07 '16 at 17:37
  • Sorry, true. I have added B and R data constructor. – lsalvatore Dec 07 '16 at 18:11
  • @DanielWagner Thanks! I haven't tried with class yet. The problem is when i define a structure. It can't be recursive – lsalvatore Dec 07 '16 at 18:34
  • @Isalvatore .Net structures can't be recursive, classes can. [Always use classes instead of structures](https://msdn.microsoft.com/en-us/library/ms229017(v=vs.110).aspx) unless you _really_ know what you're doing. Structures are passed as value types, and flattened wherever they are used; a recursive structure would be flattened into itself and either be empty or have infinite size. [Variance on structures doesn't work correctly](http://stackoverflow.com/questions/12454794/why-covariance-and-contravariance-do-not-support-value-type). – Cirdec Dec 07 '16 at 20:46

1 Answers1

1

The standard OO way of doing this would be

Public MustInherit Class HTML
    Public Tag as String
End Class

Public Class B
    Inherits HTML

    Public Content as String
End Class

Public Class R
    Inherits HTML

    Public HTML as HTML
End Class

This isn't the same as the Haskell datatype. Besides possibly being null, someone could define another class that's neither B nor R

Public Class TrickedYou
    Inherits HTML
End Class

There's another way to express sum types in .Net that matches Haskell's sum types up to nulls. It uses generics and is fairly alien to OO programming; the closest OO design pattern is a visitor, which almost gets a sum type right. The visitor OO pattern doesn't get the generic return type right.

Community
  • 1
  • 1
Cirdec
  • 24,019
  • 2
  • 50
  • 100
  • To actually use this you need to do a typecase/downcast with is ugly af. If you add a method corresponding to the appropriate fold operation or to a single layer of pattern matching to the base class, then this problem and the first one you mention are both solved. While new subclasses like `TrickedYou` can be added, they will be forced to observationally behave (modulo side-effects and downcasting) like the modeled algebraic data type. – Derek Elkins left SE Dec 08 '16 at 07:07
  • @DerekElkins That's what the last linked answer is. I have no desire to ever write generic code with variance markings in VB.Net. – Cirdec Dec 08 '16 at 07:25