Haskell fromPathPiece具有类型()

Haskell fromPathPiece具有类型(),haskell,yesod,Haskell,Yesod,我在我的页面上同时使用多个表单,当用户单击“更新”时,我需要找出哪个记录与返回的表单数据一致 现在,我正试图使用toPathPiece/fromPathPiece来实现这一点,并将密钥存储在表单上的一个隐藏文本字段中 文本返回正常,因此我返回类似“3”的内容。但当我尝试使用密钥进行替换时,会出现此错误: Handler/Song.hs:137:15: Couldn't match type ‘()’ with ‘Key SongChord’ Expected type: Hand

我在我的页面上同时使用多个表单,当用户单击“更新”时,我需要找出哪个记录与返回的表单数据一致

现在,我正试图使用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 sc_id -> do
    runDB $ replace sc_id sc
    return sc_id
下面是有问题的代码:

(_, _, 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}
        |]

查看
insert
replace
的类型(为简洁起见,忽略约束):

大小写
表达式的分支必须具有相同的类型。(否则,
sck
的类型将根据所采用的分支而有所不同。)因为
insert
replace
调用是它们各自分支中的最后一个表达式,所以它们的类型必须匹配。由于
键val
()
在它们的类型中是不同的,因此会出现该错误

通过返回键,可以使
replace
分支具有正确的类型:

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 sc_id -> do
    runDB $ replace sc_id sc
    return sc_id

查看
insert
replace
的类型(为简洁起见,忽略约束):

大小写
表达式的分支必须具有相同的类型。(否则,
sck
的类型将根据所采用的分支而有所不同。)因为
insert
replace
调用是它们各自分支中的最后一个表达式,所以它们的类型必须匹配。由于
键val
()
在它们的类型中是不同的,因此会出现该错误

通过返回键,可以使
replace
分支具有正确的类型:

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 sc_id -> do
    runDB $ replace sc_id sc
    return sc_id

好了,修好了!感谢您的帮助。并且,我们能够省去toPathPiece/fromPathPiece,直接将密钥放入隐藏字段。好的,修复了它!感谢您的帮助。并且,我们能够省去toPathPiece/fromPathPiece,直接将密钥放入隐藏字段。