How can I parse custom type in a digestive-functors form?

111 Views Asked by At

I have no problems trying to parse built-in types in a digestive-functors form, e.g I have a Client type (generated by the persistent library) that references a Country ID (of Key Country type):

Client
  :: String
     -> String
     -> String
     -> Database.Persist.Class.Key Country
     -> Maybe Int
     -> Client

Then I define a clientForm value:

clientForm :: Monad m => Form String m Client                                                                           
clientForm = Client <$> "firstName" .: string Nothing                                                                   
                    <*> "lastName"  .: string Nothing                                                              
                    <*> "address"   .: string Nothing                                                              
                    <*> "country"   .: stringRead "Cannot parse country" Nothing                                   
                    <*> "age"       .: optionalStringRead "Cannot parse age" Nothing        

Strangely, the clientForm when submitted (POST), cannot parse the country id field. enter image description here

Is it wrong to use "stringRead" to parse "Key Country" type (which can be obtained from "toSqlKey int64")?

1

There are 1 best solutions below

0
On

After some help from dmwit Freenode #haskell, the following will solve the problem:

clientForm :: Monad m => Form String m Client                                                                           
clientForm = Client <$> "firstName" .: string Nothing                                                                   
                <*> "lastName"  .: string Nothing                                                              
                <*> "address"   .: string Nothing                                                              
                <*> (toSqlKey <$> "country" .: stringRead "Cannot parse country id." Nothing)                                   
                <*> "age"       .: optionalStringRead "Cannot parse age" Nothing

I think the confusion came from the fact that "Key Country" type (a newtype) cannot be "read" directly from an integer...