I am processing a web request, and trying to save a potential entity (User / Address 1). The main question is, how can I transform a list of Strings to parameters to a function - where the list could be of arbitrary length.
I have looked at Passing list elements as parameters to curried function but this seems to be a solution only when knowing the amount of parameters in advance.
data User = User String String
data Address1 = Address1 String
let ufields = ["chris", "str"]
let afields = ["earth"]
I'm looking for a function along the lines of:
f :: [String] -> (? -> c) -> Maybe c
f fields c = undefined
So all I would need to pass is the data constructor (User/Address1), and a list of strings.
Examples:
f ufields User
would return Just ( User "chris" "str")
.
f ["chris"] User
would return Nothing
.
f [] User
would return Nothing
.
f afields Address1
would return Just ( Address1 "earth" )
.
Is this possible to be done without using TemplateHaskell? I can achieve the above manually, but it involves quite a bit of additional typing:
data User = User String String deriving (Show)
data Address1 = Address1 String deriving (Show)
data EntityType = UserEntity | AddressEntity
data EntityContainer = UserContainer User | AddressContainer Address1
f :: EntityType -> [String] -> Maybe EntityContainer
f UserEntity (p:p':[]) = Just $ UserContainer $ User p p'
f AddressEntity (p:[]) = Just $ AddressContainer $ Address1 p
f _ _ = Nothing
printPossibleEntity :: [String] -> EntityType -> IO ()
printPossibleEntity fields entityType =
case (f entityType fields) of
Just (UserContainer u) -> print u
Just (AddressContainer a) -> print a
Nothing -> print "No entity matched"
main :: IO ()
main = do
let ufields = ["chris", "str"]
let afields = ["earth"]
printPossibleEntity ufields UserEntity
printPossibleEntity afields AddressEntity
printPossibleEntity [] AddressEntity
Which outputs:
User "chris" "str"
Address1 "earth"
"No entity matched"