Reputation: 11
I'm having a problem with module recursion. I've declared some of my own data types in a file which I want to be available to Models.hs, since I need to use it in the config/models file. But one of the types needs data types from the DB. A FooId (i.e. Key Foo) to be precise.
It looks something like this:
config/models
Foo
name Text
thingy (Bar Foo) Maybe
UniqueName name
deriving Eq Show Read Typeable
My own file contains these
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)
Now I need to import Model.hs to get Key to work, but I also need to import my file into Model.hs for it to work. I've also tried adding my own types to Models.hs, but I get these errors:
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))
And adding a "deriving instance Eq a => Eq (Key a)" together with the {-# LANGUAGE StandaloneDeriving #-} doesn't work either.
If anyone knows how to remedy this, it'd help me immensely.
Upvotes: 0
Views: 82
Reputation: 11
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)
Upvotes: 1