2

フレームワークと Haskell を学習する方法として、Yesod に移植している Lift アプリがあります。アプリの一部は、TCP 層とデータベース層にのみ存在します。ソケット接続からの受信バイトを解析し、モデルが処理する更新に変換します。正規表現とパターン マッチングを使用して Scala でこれを行いましたが、Haskell では再現できませんでした。

非常に単純化された例:

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persist|
Person
    name String
    deriving Show

UnknownMessage
    text String
    deriving Show
|]

parseMsg m = runDB $ do
    case ms of
        ["add",name]       -> insert Person{personName = name}
        ["delete",name]    -> deleteWhere [PersonName ==. name]
        ["change",from,to] -> updateWhere [PersonName ==. from] [PersonName =.to]
        _                  -> insert UnknownMessage{unknownMessageText = m}
where
    ms = splitRegex (mkRegex ",") m

上記のコードは、4 つのパターン マッチのうち 3 つをコメント アウトした状態でのみコンパイルされます。"insert Person" は "deleteWhere" や "insert UnknownMessage" でさえ機能しません。結果は、私が頭も尻尾もわからないタイプの一致するエラー メッセージになる傾向があります。

上記のコードをどのように書き直すことができますか? モナドに挑戦した人のための永続的なガイドはどこにありますか? 本の章では、クエリを連鎖させる方法などについて詳しく説明していません。

編集:挿入に(>>)を追加するというhammarの提案により、問題が修正されました。「runDB $ do」を削除すると、関数の型は「parseMsg :: PersistQuery backend m => String -> backend m ()」になります。これにより、返されたクエリを後でモナド内で実行できるようになりますか? Scala で更新を行っていたように?

4

1 に答える 1

4

私は Yesod の専門家ではありませんが、ドキュメントをざっと見てみると、insertアクションが新しいレコードのキーを返し、 whileupdateWheredeleteWhere両方が を返すことが問題のように見えます()

insert      :: (...) => val -> backend m (Key backend val)
updateWhere :: (...) => [Filter val] -> [Update val] -> backend m ()
deleteWhere :: (...) => [Filter val] -> backend m ()

おそらく、ここではキーを気にしないので、次のようにして破棄できます

insert Person{personName = name} >> return ()

タイプチェックを行う必要があります。

于 2012-09-27T19:11:43.590 に答える