Reputation: 407
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 Term
s 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
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