我遇到模块递归问题。我已经在一个文件中声明了我自己的一些数据类型,我希望它可以用于Models.hs,因为我需要在config / models文件中使用它。 但其中一种类型需要来自数据库的数据类型。确切地说是FooId(即Key Foo)。
它看起来像这样:
配置/模型
Foo
name Text
thingy (Bar Foo) Maybe
UniqueName name
deriving Eq Show Read Typeable
我自己的文件包含这些
data Bar record = Bar { a :: [Jab record] }
deriving (Eq, Show, Read, Typeable)
data Jab record = Jab { b :: Key record
, c :: Int
}
deriving (Eq, Show, Read, Typeable)
现在我需要导入Model.hs以使Key工作,但我还需要将我的文件导入Model.hs才能工作。 我也尝试将自己的类型添加到Models.hs,但是我收到了这些错误:
Model.hs:24:13:
No instance for (Eq (Key record))
arising from the first field of ‘Jab’ (type ‘Key record’)
Possible fix:
use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
When deriving the instance for (Eq (Jab record))
添加"派生实例Eq a => Eq(键a)" 与{ - #LANGUAGE StandaloneDeriving# - }一起使用也不起作用。
如果有人知道如何解决这个问题,它会帮助我。
答案 0 :(得分:1)
Turns out writing my own instances for (Jab record)
fixed this issue.
This is how I fixed it, for reference:
Eq
, Show
and Read
from the deriving
clause of Jab
Eq
, Show
and Read
instances for (Jab record)
PersistField
instance for (Bar record)
(The following is all put in a separate file to be imported to Models.hs
)
module Custom.TypesAndInstances where
import ClassyPrelude.Yesod
import Prelude (read)
import qualified Data.Text as T
import qualified Text.Read.Lex as L
import Text.ParserCombinators.ReadPrec
import GHC.Read
import GHC.Show (appPrec)
-- instance for PersistField (Bar record)
instance (PersistEntity record, PersistField record) => PersistField (Bar record) where
toPersistValue = PersistText . T.pack . show
fromPersistValue (PersistText t) = Right $ read $ T.unpack t
-- instances for Jab Eq, Read and Show
instance PersistEntity record => Eq (Jab record) where
Jab x a == Jab y b = x == y && a == b
instance PersistEntity record => Show (Jab record) where
show (Jab x a) = "Jab " ++ show x ++ " " ++ show a
instance PersistEntity record => Read (Jab record) where
readPrec = parens
(prec appPrec (do
expectP (L.Ident "Jab")
x <- step readPrec
y <- step readPrec
return (Jab x y))
)
readListPrec = readListPrecDefault
readList = readListDefault
----------------------
data Bar record = Bar { a :: [Jab record]
}
deriving (Eq, Show, Read, Typeable)
data Jab record = Jab { b :: Key record
, c :: Int
}
deriving (Typeable)