python-3.xelm

How to understand this Elm function


I have been trying to understand the following function and I think I am interpreting it incorrectly. I am trying to convert it to Python3:

type UITreeNodeChild
    = UITreeNodeChild UITreeNode


unwrapUITreeNodeChild : UITreeNodeChild -> UITreeNode
unwrapUITreeNodeChild child =
    case child of
        UITreeNodeChild node ->
            node

I see the bottom part is that there is a function called unwrapUITreeNodeChild which has a arg called child which is of UITreeNodeChild and the function returns a UITreeNode.

In Python I see it as:

class UITreeNodeChild(Enum):
  UITreeNodeChild=UITreeNode

def unwrapUITreeNodeChild(child: UITreeNodeChild) -> UITreeNode:
  if child is UITreeNodeChild:  # 
    pass                        # I have no idea what it really means.

I don't understand the rest of the function signature. After looking at the ELM docs, I was confused as the switch but it looks like it is passing node into the definition of UITreeNodeChild.

I know I'm wrong here. What am I missing?

Edit

So it is looking for a typecheck essentially in the sample, so what you would want to do is confirm that it is that type and then use this new property in underlying code. It would look somewhat similar to:

class UITreeNodeChild:
  pass

def unwrapUITreeNodeChild(child: UITreeNodeChild) -> UITreeNode:
  if type(child) == UITreeNodeChild:  
    pass                        

Note you want to check type not check the exact same object.


Solution

  • You are looking at a tagged union and a simple pattern match against that tagged union.

    In type UITreeNodeChild = UITreeNodeChild UITreeNode, the UITreeNodeChild on the right side is the tag. UITreeNode is the data type that is tagged.

    When you say:

    case child of
        UITreeNodeChild node ->
            node
    

    You are pattern matching child against a pattern that begins with UITreeNodeChild. The tagged data type value is bound to the name node and this is also what it is returned from the case expression for this patten match.

    Since this tagged union has only one variant you also have the option to unpack it in the parameter declaration:

    unwrapUITreeNodeChild : UITreeNodeChild -> UITreeNode
    unwrapUITreeNodeChild (UITreeNodeChild node) =
         node
    

    The way you do this in python depends on the way you chose to implement the tagged union. The general method is the same. You have to have some kind of tag and you have to have a way to determine the tag of a value. You can then return the embedded data type based on the tag. With a single tag this becomes just returning the embedded data type.