我最近一直在玩MySQL-Simple.试图为该库提供一些全面的例子.我想将ID与我想要存储的实际记录分开.要为此Entity数据类型实现QueryResults的错误情况,我需要此数据类型实际使用的字段数量.因此我介绍了一个Arity类型类(很容易出错,特别是在数据发生变化时).我也在undefined这里用来调用方法的正确实例arity.
我在几个例子中看过这样的东西,但我对undefined这里的使用感到不安.有没有更好的方法来做到这一点?
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE BangPatterns #-}
module Main where
import Database.MySQL.Simple
import Database.MySQL.Simple.QueryResults
import Database.MySQL.Simple.QueryParams
import Database.MySQL.Simple.Result
import Database.MySQL.Simple.Param
connectInfo :: ConnectInfo
connectInfo = defaultConnectInfo { connectUser = "dbuser" }
data Person = Person { personName :: String
, personAge :: Int
} deriving Show
class Arity a where
arity :: a -> Int
instance Arity Person where
arity _ = 2
instance QueryResults Person where
convertResults [fname, fage] [vname, vage] =
Person name age
where
!name = convert fname vname
!age = convert fage vage
convertResults fs vs = convertError fs vs 2
instance QueryParams Person where
renderParams (Person name age) = [render name, render age]
data Entity a = Entity Int a
instance (Arity a, QueryResults a) => QueryResults (Entity a) where
convertResults (fid:fs) (vid:vs) =
Entity id value
where
!id = convert fid vid
!value = convertResults fs vs
convertResults fs vs =
convertError fs vs (1 + arity (undefined :: Person))
Run Code Online (Sandbox Code Playgroud)
亲切的问候,raichoo
如果arity应该只依赖于它的选择a,即它的类型,你应该使用基本上带有幻像类型标记的代理():
class Arity a where
arity :: proxy a -> Int
Run Code Online (Sandbox Code Playgroud)
这样,实例Arity被迫不会尝试查看传递的值,而客户端不需要传递底部:
instance Arity Person where
arity _ = 2
convertResults fs vs =
convertError fs vs (1 + arity (Proxy :: Proxy Person))
Run Code Online (Sandbox Code Playgroud)
我认为没关系.如果您想要非undefined替代方案,可以使用代理幻像类型:
data Proxy a = Proxy
class Arity a where
arity :: Proxy a -> Int
instance Arity Person where
arity _ = 2
convertResults fs vs =
convertError fs vs (1 + arity (Proxy :: Proxy Person))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
112 次 |
| 最近记录: |