我最近一直在研究 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))
亲切的问候,raichoo
最佳答案
如果 arity
应该只依赖于 a
的选择,即它的类型,你应该使用 Proxy这基本上是带有幻影类型标签的 ()
:
class Arity a where
arity :: proxy a -> Int
这样,Arity
的实例就被强制不尝试查看传递的值,并且客户端不需要传递底部:
instance Arity Person where
arity _ = 2
convertResults fs vs =
convertError fs vs (1 + arity (Proxy :: Proxy Person))
关于mysql - 这是 "undefined"的合法使用还是有更好的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28475751/