haskell - FromRow instance for nested type with postgresql-simple -
i using following types represent user:
data credentialsrep utype ptype = credentials { username :: utype , password :: ptype } deriving (show) data namerep ftype ltype = name { first :: ftype , last :: ltype } deriving (show) data userrep ctype ntype = user { credentials :: ctype , name :: ntype} deriving (show) how can write fromrow instance userrep postgresql-simple can turn queries useful types? far, have this:
instance fromrow (userrep b) fromrow = username <- field password <- field fname <- field lname <- field return $ (user (credentials username password) (name fname lname)) which results in error:
src/psqltest.hs:30:5: couldn't match type ‘a’ ‘credentialsrep utype0 ptype0’ ‘a’ rigid type variable bound instance declaration @ src/psqltest.hs:24:10 expected type: rowparser (userrep b) actual type: rowparser (userrep (credentialsrep utype0 ptype0) (namerep ftype0 ltype0)) relevant bindings include password :: ptype0 (bound @ src/psqltest.hs:27:5) username :: utype0 (bound @ src/psqltest.hs:26:5) fromrow :: rowparser (userrep b) (bound @ src/psqltest.hs:25:3) in stmt of 'do' block: return $ (user (credentials username password) (name fname lname)) in expression: { username <- field; password <- field; fname <- field; lname <- field; .... } in equation ‘fromrow’: fromrow = { username <- field; password <- field; fname <- field; .... } src/psqltest.hs:30:5: couldn't match type ‘b’ ‘namerep ftype0 ltype0’ ‘b’ rigid type variable bound instance declaration @ src/psqltest.hs:24:10 expected type: rowparser (userrep b) actual type: rowparser (userrep (credentialsrep utype0 ptype0) (namerep ftype0 ltype0)) relevant bindings include lname :: ltype0 (bound @ src/psqltest.hs:29:5) fname :: ftype0 (bound @ src/psqltest.hs:28:5) fromrow :: rowparser (userrep b) (bound @ src/psqltest.hs:25:3) in stmt of 'do' block: return $ (user (credentials username password) (name fname lname)) in expression: { username <- field; password <- field; fname <- field; lname <- field; .... } in equation ‘fromrow’: fromrow = { username <- field; password <- field; fname <- field; .... }
(disclaimer: haven't used library @ all)
you're trying define fromrow userrep b, in definition of fromrow you're explicitly constructing userrep (credentialsrep u p) (namerep f l), hence error saying can't match a credentialsrep u p , b namerep f l (modulo type variable names). instead, believe can like
instance (fromfield u, fromfield p, fromfield f, fromfield l) => fromrow (userrep (credentialsrep u p) (namerep f l)) fromrow = username <- field password <- field firstname <- field lastname <- field return $ user (credentials username password) (name firstname lastname) or just
instance fromrow (userrep (credentialsrep string string) (namerep string string)) ... with same fromrow definition. approach may have enable flexibleinstances extension.
in addition, looks may making types polymorphic (but situation might unique, take advice grain of salt), rid of type parameters altogether , have
data credentialsrep = credentials { username :: string , password :: string } deriving (show) data namerep = name { first :: string , last :: string } deriving (show) data userrep = user { credentials :: credentialsrep , name :: namerep } deriving (show) in case need
instance fromrow userrep ... with same fromrow definition.
Comments
Post a Comment