xafizoff
xafizoff

Reputation: 407

Build data constructor using generics in Haskell

How to construct a value by given constructor name and constructor arguments. For example, having the following data type

{-# LANGUAGE DeriveGeneric #-}

data Test = Foo | Bar Int | Baz String Int deriving (Generic, Show)

I would have such function

make "Foo" -- > Foo
make "Bar" 1 -- > Bar 1
make "Baz" "hi" 777 -- > Baz "hi" 777

The solution in this article is pretty close, but it works for data types only with single data constructor.

EDIT

So why do I want to do this? I have a BERT-encoded data that comes from the client. I can decode it to the Terms from the bert package. I want to have something like this

case x of
  Foo -> do something
  Bar x -> do something with x

and so on instead of

case x of
  TupleTerm y ->
    case y of
      [AtomTerm "foo"] -> do something
      [AtomTerm "bar", IntTerm x] -> do something with x

EDIT2

I concluded, that I was going in the wrong way.

Upvotes: 0

Views: 200

Answers (1)

John F. Miller
John F. Miller

Reputation: 27217

"I have a BERT encoded data, that comes from the web browser"

There is not a reasonable way to solve the problem as you have posed it. However, if you are parsing data and you want to turn it into a Haskell data structure, the place to select the constructor is within the parser. Something like:

make :: Parser Test
make = do
  tag <- parse string
  case tag of
    "Foo" -> Foo
    "Bar" -> Bar <$> int
    "Baz" -> Baz <$> string <*> int

sting :: Parser String
int   :: Parser Int

Upvotes: 1

Related Questions