THRIFT-5072 Fix data type generation.
Client: hs
Patch: Homarechan <tikuwakunn@icloud.com>

This closes #1974
diff --git a/CHANGES.md b/CHANGES.md
index 1dddab9..abd709b 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -8,6 +8,7 @@
 - [THRIFT-4981](https://issues.apache.org/jira/browse/THRIFT-4981) - Remove deprecated netcore bindings from the code base
 - [THRIFT-5006](https://issues.apache.org/jira/browse/THRIFT-5006) - Implement DEFAULT_MAX_LENGTH at TFramedTransport
 - [THRIFT-5069](https://issues.apache.org/jira/browse/THRIFT-5069) - In Go library TDeserializer.Transport is now typed \*TMemoryBuffer instead of TTransport
+- [THRIFT-5072](https://issues.apache.org/jira/browse/THRIFT-5072) - Haskell generator fails to distinguish between multiple enum types with conflicting enum identifiers
 
 ### Java
 
diff --git a/compiler/cpp/src/thrift/generate/t_hs_generator.cc b/compiler/cpp/src/thrift/generate/t_hs_generator.cc
index a59dee5..00c01a1 100644
--- a/compiler/cpp/src/thrift/generate/t_hs_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_hs_generator.cc
@@ -305,7 +305,7 @@
 
   bool first = true;
   for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
-    string name = capitalize((*c_iter)->get_name());
+    string name = capitalize(tenum->get_name()) + "_" + capitalize((*c_iter)->get_name());
     f_types_ << (first ? "" : "|");
     f_types_ << name;
     first = false;
@@ -321,7 +321,7 @@
   indent_up();
   for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
     int value = (*c_iter)->get_value();
-    string name = capitalize((*c_iter)->get_name());
+    string name = capitalize(tenum->get_name()) + "_" + capitalize((*c_iter)->get_name());
     indent(f_types_) << name << " -> " << value << endl;
   }
   indent_down();
@@ -329,7 +329,7 @@
   indent_up();
   for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
     int value = (*c_iter)->get_value();
-    string name = capitalize((*c_iter)->get_name());
+    string name = capitalize(tenum->get_name()) + "_" + capitalize((*c_iter)->get_name());
     indent(f_types_) << value << " -> " << name << endl;
   }
   indent(f_types_) << "_ -> X.throw T.ThriftException" << endl;
diff --git a/test/hs/TestClient.hs b/test/hs/TestClient.hs
index 93fb591..d014e08 100644
--- a/test/hs/TestClient.hs
+++ b/test/hs/TestClient.hs
@@ -193,16 +193,16 @@
 
   -- Enum Test
   putStrLn "testEnum"
-  numz1 <- Client.testEnum prot ONE
-  when (numz1 /= ONE) exitFailure
+  numz1 <- Client.testEnum prot Numberz_ONE
+  when (numz1 /= Numberz_ONE) exitFailure
 
   putStrLn "testEnum"
-  numz2 <- Client.testEnum prot TWO
-  when (numz2 /= TWO) exitFailure
+  numz2 <- Client.testEnum prot Numberz_TWO
+  when (numz2 /= Numberz_TWO) exitFailure
 
   putStrLn "testEnum"
-  numz5 <- Client.testEnum prot FIVE
-  when (numz5 /= FIVE) exitFailure
+  numz5 <- Client.testEnum prot Numberz_FIVE
+  when (numz5 /= Numberz_FIVE) exitFailure
 
   -- Typedef Test
   putStrLn "testTypedef"
diff --git a/test/hs/TestServer.hs b/test/hs/TestServer.hs
index b7731ab..c37dda3 100644
--- a/test/hs/TestServer.hs
+++ b/test/hs/TestServer.hs
@@ -212,10 +212,10 @@
 
   testInsanity _ x = do
     System.IO.putStrLn "testInsanity()"
-    return $ Map.fromList [ (1, Map.fromList [ (TWO  , x)
-                                             , (THREE, x)
+    return $ Map.fromList [ (1, Map.fromList [ (Numberz_TWO  , x)
+                                             , (Numberz_THREE, x)
                                              ])
-                          , (2, Map.fromList [ (SIX, default_Insanity)
+                          , (2, Map.fromList [ (Numberz_SIX, default_Insanity)
                                              ])
                           ]
 
diff --git a/test/hs/ThriftTest_Main.hs b/test/hs/ThriftTest_Main.hs
index 670023e..6421c6a 100644
--- a/test/hs/ThriftTest_Main.hs
+++ b/test/hs/ThriftTest_Main.hs
@@ -107,7 +107,7 @@
         return (Map.fromList [(1, Map.fromList [(2, 2)])])
 
     testInsanity _ x = do
-        return (Map.fromList [(1, Map.fromList [(Types.ONE, x)])])
+        return (Map.fromList [(1, Map.fromList [(Types.Numberz_ONE, x)])])
 
     testMulti _ _ _ _ _ _ _ = do
         return (Types.Xtruct "" 0 0 0)
diff --git a/tutorial/hs/HaskellClient.hs b/tutorial/hs/HaskellClient.hs
index bd29df0..76a8824 100644
--- a/tutorial/hs/HaskellClient.hs
+++ b/tutorial/hs/HaskellClient.hs
@@ -48,7 +48,7 @@
   printf "1+1=%d\n" sum
 
 
-  let work = Work { work_op = DIVIDE,
+  let work = Work { work_op = Operation_DIVIDE,
                     work_num1 = 1,
                     work_num2 = 0,
                     work_comment = Nothing
@@ -58,7 +58,7 @@
         (\e -> printf "InvalidOperation %s\n" (show (e :: InvalidOperation)))
 
 
-  let work = Work { work_op = SUBTRACT,
+  let work = Work { work_op = Operation_SUBTRACT,
                     work_num1 = 15,
                     work_num2 = 10,
                     work_comment = Nothing
diff --git a/tutorial/hs/HaskellServer.hs b/tutorial/hs/HaskellServer.hs
index cfe1344..1594ee3 100644
--- a/tutorial/hs/HaskellServer.hs
+++ b/tutorial/hs/HaskellServer.hs
@@ -64,13 +64,13 @@
     printf "calculate(%d, %s)\n" logid (show work)
 
     let val = case op work of
-                ADD ->
+                Operation_ADD ->
                     num1 work + num2 work
-                SUBTRACT ->
+                Operation_SUBTRACT ->
                     num1 work - num2 work
-                MULTIPLY ->
+                Operation_MULTIPLY ->
                     num1 work * num2 work
-                DIVIDE ->
+                Operation_DIVIDE ->
                     if num2 work == 0 then
                         throw $
                               InvalidOperation {