简体   繁体   中英

Can you mix record syntax with enumerations in Haskell data types?

I've written the following:

data Expression = Expression { lhs :: Int, rhs :: Expression } | Int

The problem is if I try to construct an Expression with just an int I get a partially applied function. What's the best way to fix this?

Things to know up front:

  • every data constructor in a Haskell data declaration has its own name
  • data constructors live in an entirely separate namespace from type names

As the comments note, you are defining both a type named Expression and a data constructor named Expression . Because Haskell has separate namespaces for types and data constructors, the compiler is fine with this.

Also, you are creating a second data constructor named Int (which likewise doesn't conflict with the existing type named Int ). This is probably not what you want, and is confusing to boot!

When you try to construct a value such as myExpr = Expression xy , you are using the first data constructor, not the type name or the second data constructor. The Expression data constructor expects two arguments: first an Int , then an Expression . That is why, if you just provide the first argument, you will get a partially applied function.


A corrected, more idiomatic version of your example might be:

data Expression = Assignment { lhs :: Int, rhs :: Expression }
                | Literal { value :: Int }

It is actually fairly common to see a data constructor with the same name as its type, if it is the only data constructor:

data Foo = Foo { unwrapFoo :: Int }

For the sake of completeness, the answer to your question is yes. The other answer provides an excellent explanation of what your current code does, but the short answer to your question is that

data Expression = Assignment { lhs :: Int, rhs :: Expression }
                | Literal Int

is a completely valid type declaration. That being said, it's not tremendously idiomatic, so if you're going to use record syntax, you should probably use it for each data constructor of a given type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM