2

たとえば、別のDB.hsファイルにランダムなDB関数があります。このようなもの:

savePerson :: Person -> IO ()
  savePerson p = do
  c <- connect
  run c "INSERT INTO persons (name, age) \
        \VALUES (?, ?)"
        [toSql (personName p), toSql (personAge p)]
  commit c
  disconnect c
  return ()

DB.hsをインポートした場合、Site.hsのハンドラー内でこの関数を実行するにはどうすればよいですか?

このようにハンドラーに貼り付けるだけの場合(これは単なる例です):

insertPerson = do
  par <- getPostParams
  let p = toPerson par
  savePerson p
  return ()
  where
    toPerson m =
      Person {personName = head (m ! (B.pack "name"))
             ,personAge  = read (B.unpack (head (m ! (B.pack "age")))) :: Int
             }

これは動作しません。ハンドラーに何かを返させたくありません。Personを保存するだけで、何も返さない/レンダリングしないようにします。

それを行う正しい方法は何ですか?

ありがとう。

4

1 に答える 1

1

あなたの問題は、単位の種類と値が何であるかを理解していないようです。

単位型は、"()" と呼ばれる特別な組み込み型であり、"()" とも呼ばれる値を 1 つだけ持ちます。

たとえば、「ユニットのリスト」タイプの 4 つのユニットのリストを作成できます。

fourUnits :: [()]
fourUnits = [(), (), (), ()]

ユニット タイプは、他の情報が必要ない場合に使用されます。したがって、技術的には、タイプ「IO ()」は、単位値を与える IO アクションのタイプです。

"do" 句は、">>=" の呼び出しの連鎖を緩和します。>>= はタイプを持っています

(>>=) :: (Monad m) => m a -> (a -> m b) -> m b

つまり、「do」句の型は、最後のアクションによって返された型です。

だからあなたが言うところ

savePerson p
return ()

「return ()」は「savePerson p」とまったく同じ型であるため、偽です。

「リターン」は制御の流れとは何の関係もないことに注意してください。それは単に型を持つ関数です。

return :: (Monad m) => a -> m a

この混乱を避けるために、「ラップ」または「注入」または同様の名前を付けたほうがよいでしょう。

于 2012-03-25T12:53:41.723 に答える