0

I have a list of country id and country text in json

{
 1 : "country one",
 2 : "country two"
}

I have created below code to represent country id and text in haskell

data Country a = Country a

country1 :: Country String -- Representing country name
country1 = Country "country one"

country2 :: Country Integer -- Representing country id
country2 = Country 2 

Above code is working fine. But I want to put constraint of a to take only values of String and Integer.

For that I tried below code . However, it is not working.

{-# LANGUAGE GADTs #-}
data Country a where
    Country :: (String, Integer) => a -> Country a

toId :: Country String -> Country Integer
toId Country a = Country 1

toText :: Country Integer -> Country String
toText Country a = Country "country one"

Can anyone help to figure out how I can implement the above code in best way so that it is working ?

navin
  • 165
  • 1
  • 12
  • This representation is quite weird. I would expect that a country carries both its id and name, so `Country Int String` as a constructor. Exhaustively enumerating possible types for `a` is also quite an anti-pattern, since it prevents code reuse. – Willem Van Onsem Jan 21 '18 at 16:51
  • Actually in the json post I will receive the country name and that will be converted to country id while saving in database . post data will be like {"country" : "country one"} . Hence I am trying to represent country name and id seperately. – navin Jan 21 '18 at 16:56
  • You say, "I want to put constraint of `a` to take only values of `String` and `Integer`". Why do you want this constraint? – Daniel Wagner Jan 22 '18 at 23:36
  • Because in my use case only those two types are valid. Since a is polymorphic anyone can write Country SomeOtherType which is invalid type for Country. I hope that makes sense. – navin Jan 23 '18 at 06:02

1 Answers1

0

GADT's is an overkill for this task, IMO.

Can't you just use ADT?

data Country = CountryWithInt Int
             | CountryWithString String
arrowd
  • 33,231
  • 8
  • 79
  • 110
  • I agree that GADTs are overkill, but this representation seems strictly worse than `data Country a = Country a`: one cannot write the types `Country Int -> Country String` and vice versa that guarantee that the given country identifier is in the appropriate format at input and output. – Daniel Wagner Jan 22 '18 at 23:51
  • Is this a better representation ? `newtype CountryId = CountryId Int` and `newtype CountryText = CountryText String` or should I actually look into GADTs instead ? – navin Jan 23 '18 at 06:04
  • Yes, this is definitely better representation if you want to write functions like `Country Int -> Country String`. Note that your types share nothing between them, so it was wrong idea to wrap them into a single type. – arrowd Jan 23 '18 at 06:40