我在我的网页上一次使用多个表单,当用户点击“更新”时,我需要确定哪条记录与返回的表单数据一致。
现在我正在尝试使用toPathPiece / fromPathPiece执行此操作,并将密钥存储在表单上的隐藏文本字段中。
文本返回正常,所以我得到了类似“3”的内容。但是当我尝试使用密钥进行替换时出现此错误:
Handler/Song.hs:137:15:
Couldn't match type ‘()’ with ‘Key SongChord’
Expected type: HandlerT App IO (Key SongChord)
Actual type: HandlerT App IO ()
In a stmt of a 'do' block: runDB $ replace sc_id sc
In the expression: do { runDB $ replace sc_id sc }
In a case alternative:
Just sc_id -> do { runDB $ replace sc_id sc }
以下是有问题的代码:
(_, _, Just _) -> do
chordz <- runDB $ selectList [SongChordSong ==. sid] [Asc SongChordSeqnum]
chordroots <- runDB $ selectList [] []
notesets <- runDB $ selectList [] []
let rootz = map (\(Entity crid cr) -> (chordRootName cr, crid)) chordroots
nsetz = map (\(Entity nsid ns) -> (noteSetName ns, nsid)) notesets
((res, widget),enctype) <-
runFormPost $ scfForm Nothing sid (length chordz) rootz nsetz
case res of
FormSuccess scf -> do
-- fromScf takes the form datatype and returns (Text,SongChord)
let (mbsctext, sc) = fromScf scf
mbscid = fromPathPiece mbsctext :: Maybe (Key SongChord)
sck <- case mbscid of
Nothing -> do
runDB $ insert sc
Just sc_id -> do
-- runDB $ insert sc
-- here's the problem!
runDB $ replace sc_id sc
defaultLayout $ [whamlet|
<h1> #{show mbscid}
<br> #{show sck}
<br> #{show scf}
|]
如果我注释掉替换(并取消注释插入)然后它编译并运行,结果网页上有mbscid,看起来它是一个有效的密钥。在这种情况下,这是页面中的文本:
Just (SongChordKey {unSongChordKey = SqlBackendKey {unSqlBackendKey = 2}})
SongChordKey {unSongChordKey = SqlBackendKey {unSqlBackendKey = 16}}
Scf {song = SongKey {unSongKey = SqlBackendKey {unSqlBackendKey = 1}}, chordroot = ChordRootKey {unChordRootKey = SqlBackendKey {unSqlBackendKey = 9}}, noteset = NoteSetKey {unNoteSetKey = SqlBackendKey {unSqlBackendKey = 2}}, seqnum = 15, duration = 202, scid = "2"}
Insert copyright statement here
答案 0 :(得分:4)
查看insert
和replace
的类型(忽略简洁约束):
insert :: val -> m (Key val)
replace :: Key val -> val -> m ()
case
表达式的分支必须具有相同的类型。 (否则sck
的类型将根据所采用的分支而有所不同。)因为insert
和replace
调用是其各自分支中的最后一个表达式,所以它们的类型必须匹配。由于其类型中的Key val
和()
不同,因此您会收到该错误。
您可以通过返回密钥来使replace
分支具有正确的类型:
Just sc_id -> do
runDB $ replace sc_id sc
return sc_id