【发布时间】:2013-07-02 02:38:49
【问题描述】:
我基本上是想看看我是否可以在 Haskell 中模拟 ORM 框架,这样如果用户想要制作数据库模型,他们会做这样的事情
data Car = Car {
company :: String,
model :: String,
year :: Int
} deriving (Model)
表格是“汽车”,列是公司、型号、年份
要在 Haskell 中执行此操作,您必须结合使用类和泛型,这就是我遇到的问题。使用本教程 (http://www.haskell.org/ghc/docs/7.4.1/html/users_guide/generic-programming.html),我想出了这个(基本上是复制和重命名,所以我可以让代码正常工作)
{-# LANGUAGE DeriveGeneric, TypeOperators, TypeSynonymInstances, FlexibleInstances #-}
module Main where
import GHC.Generics
class SModel b where
s_new :: b -> IO()
instance SModel Int where
s_new s = putStrLn s++":Int"
instance SModel Integer where
s_new s = putStrLn s++":Integer"
instance SModel String where
s_new s = putStrLn s++":String"
class Model m where
new :: m a -> IO()
instance Model U1 where
new U1 = putStrLn "unit"
instance (Model a, Model b) => Model (a :*: b) where
new (a :*: b) = do
new a
new b
instance (Model a, Model b) => Model (a :+: b) where
new (L1 x) = new x
new (R1 x) = new x
instance (Model a) => Model (M1 i c a) where
new (M1 x) = new x
instance (SModel a) => Model (K1 i a) where
new (K1 x) = s_new x
data Car = Car {
company :: String,
model :: String,
year :: Int
} deriving (Model)
以上代码会报错
Cannot derive well-kinded instance of form `Model (Car ...)'
Class `Model' expects an argument of kind `* -> *'
In the data declaration for `Car'
我有点卡在这一点上,我相信我已经实例化了所有必需的泛型类型来覆盖记录
【问题讨论】:
-
您不能在派生子句中使用
Model。相反,您应该派生Generic,然后为SModel提供默认实例。请参阅“通用默认值”的 GHC 用户指南。 github.com/kosmikus/generic-deriving/blob/master/src/Generics/… 上还有一些初步改进的文档 -
所以 Haskell 没有官方支持使用 deriving 除了 show、eq(以及其他一些内置的衍生工具)
标签: generics haskell record deriving