Can enum have a non-integer representation?

Hi there, I understand an enum type is integers under the hood, but since this is Solidity in which hashed values are often calculated, I’m wondering if an enum can be converted to its nominal value. Let me give you an example. The two functions below would return the same hashed value if ActionChoices.GoRight is provided for getKey and 1 is provided for getKey2. This defeats the purpose of using an enum, which I believe should carry more values than a discrete set of integers, especially when used for hashing. Any way to easily convert an enum value to its nominal representation? i.e., a ActionChoices.GoRight value is used as GoRight in hashing. Thanks.

contract Test {
    enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill }

    ActionChoices _aChoice;

    function getKey(ActionChoices aChoice) public returns(bytes32) {
        return keccak256(abi.encodePacked("Choice: ", aChoice));
    }

    function getKey2(uint256 index) public returns(bytes32) {
        return keccak256(abi.encodePacked("Choice: ", index));
    }
}

I’m wondering if an enum can be converted to its nominal value.

Sure it can. uint8(aChoice) or uint(aChoice) work just fine.

abi.encodePacked() does not distinguish between enums and integers because there are no enums in the ABI. This is for example why you cannot overload external functions between an integer and an enum - they are not distinguishable in external calls:

contract C {
    enum ActionChoices {GoLeft, GoRight, GoStraight, SitStill}

    function getKey(ActionChoices aChoice) external {}
    function getKey(uint8 index) external {}
}
Error: Function overload clash during conversion to external types for arguments.
 --> test.sol:5:5:
  |
5 |     function getKey(uint8 index) external {}
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This defeats the purpose of using an enum, which I believe should carry more values than a discrete set of integers, especially when used for hashing. Any way to easily convert an enum value to its nominal representation? i.e., a ActionChoices.GoRight value is used as GoRight in hashing.

There’s no such nominal representation in Solidity. The representation of an enum value is just an integer. If you want it to be distinguishable, you have to incorporate the type into the hash input. E.g. keccak256(abi.encodePacked("Choice[ActionChoices]: ", aChoice)).