1

私はいくつかの mysql-simple データベース コードを書いており、データ型を QueryResults 型クラスのメンバーにして、簡単に非武装化できるようにしています。

しかし、私は次のような多くの機能で終わっています:

data FullName {
  first_name :: String,
  middle_name :: String,
  last_name :: String
} deriving Show

newtype UID = UID Integer deriving Show

go :: [(String, String)] -> Maybe FullName
go fvs = do
  first  <- lookup "first_name" fvs
  middle <- lookup "middle_name" fvs
  last   <- lookup "last_name" fvs
  return $ FullName first middle last

go :: [(String, String)] -> Maybe UID
go fvs = do
  uid <- lookup "uid" fvs
  return $ UID (read uid)

ルックアップが返される場所(おそらくa)。これらのデータ型の中には、多数の列が含まれているものがあるため、面倒です。

したがって、このようなデータ型がたくさんあり、次のように呼び出す関数を記述できるようにしたいと考えています。

go RealName ["first_name","middle_name","last_name"] fvs
go UID ["uid"] fvs

しかし、そのようなものがどのようなものであるべきか、またはどのように対処するかはわかりません。たぶん、これも不可能です。

4

3 に答える 3

3

Template Haskellを使用すると、次のようなコードになる可能性があると思います。

makeGo ''FullName

それはに展開します

goFullName :: [(String, String)] -> Maybe FullName
goFullName fvs = do
  first  <- lookup "first_name" fvs
  middle <- lookup "middle_name" fvs
  last   <- lookup "last_name" fvs
  return $ FullName first middle last

余談: if youimport Control.Applicativeは、次goFullNameのようにもっと簡潔に書くことができます。

goFullName :: [(String, String)] -> Maybe FullName
goFullName fvs
   = FullName <$> lookup "first_name" fvs
              <*> lookup "middle_name" fvs
              <*> lookup "last_name" fvs
于 2012-07-19T17:39:20.057 に答える
2

この関数を次のように記述します

import Control.Applicative

go :: [(String, String)] -> Maybe FullName
go fvs = FullName <$> l "first_name" <*> l "middle_name" <*> l "last_name"
    where l field = lookup field fvs
于 2012-07-19T17:47:44.067 に答える
0

最終的にインスタンスを作成することが目標である場合はQueryResults、次のようなことをしてみませんか。

{-# LANGUAGE GeneralizedNewtypeDeriving,OverloadedStrings #-}

Module Main where

import Database.MySQL.Simple
import Database.MySQL.Simple.QueryResults
import Database.MySQL.Simple.Result
import Database.MySQL.Simple.Param

data FullName =
  FullName {
       first_name  :: String
     , middle_name :: String
     , last_name   :: String
  } deriving Show

newtype UID = UID Integer deriving (Show,Param)

instance QueryResults FullName where
  convertResults fs@[_,_,_] vs@[_,_,_] = FullName first middle last
    where [first,middle,last] = zipWith convert fs vs
  convertResults fs vs  = convertError fs vs 3

instance QueryResults UID where
  convertResults fs@[fuid] vs@[vuid] = UID (convert fuid vuid)
  convertResults fs vs  = convertError fs vs 1

uidToFullName :: UID -> IO FullName
uidToFullName (UID uid) =
  do conn <- connect defaultConnectInfo
     [fn] <- query conn
         "SELECT first_name,middle_name,last_name FROM user WHERE uid = ?" [uid]
     return fn

サンプルセッション:

λ> :load Main.sh
λ> uidToFullName (UID 23)
FullName {first_name = "John", middle_name = "Horatio", last_name = "Smith"}

付随するSQLは次のとおりです。

CREATE TABLE user (
  uid Integer PRIMARY KEY,
  email Text,
  first_name Text,
  middle_name Text,
  last_name Text
);

INSERT INTO user VALUES (23,'john.horation@smith.com','John','Horatio','Smith');
于 2012-07-19T21:44:23.717 に答える