I'm writing markov chain generator with Haskell, using weighted list for randomly selecting elements. When I'm testing the configuration, I get an error "Couldn't match type ‘Item a0’ with ‘[Item [Char]]’". I suspect this is somehow related to the fact that Item
is parametrized and type checked doesn't realize that elements in configContinuations
have correct type (hence a0
vs. [Char]
.
I have function with signature addElement :: forall a. Ord a => Maybe a -> a -> Config a -> Config a
that had similar problem, before I added forall a
quantifier.
However, if I'm checking value as: config ^? (configContinuationsL . at "AA" . _Just . itemFreqL) `shouldBe` Just 1
, I don't know how to do similar thing.
Below are definitions for Config
, Item
, Frequency
and lenses used to operate with them.
data Frequency a = Frequency Int a
deriving (Show, Read, Eq)
data Config a = Config
{ configStarts :: ![Item a]
, configContinuations :: !(M.Map a [Item a])
} deriving (Show, Read, Eq)
data Item a =
Item (Frequency (Maybe a))
deriving (Show, Read, Eq)
makeLensesFor [ ("configStarts", "configStartsL")
, ("configContinuations", "configContinuationsL")] ''Config
itemFreqL :: Lens' (Item a) Int
itemFreqL = lens (\(Item (Frequency n _)) -> n)
(\(Item (Frequency _ a)) n -> (Item (Frequency n a)))
What should I change, so I could force types to match?
Edit: Full error message
• Couldn't match type ‘Item a0’ with ‘[Item [Char]]’
Expected type: (Int
-> Data.Functor.Const.Const (Data.Monoid.First Int) Int)
-> [Item [Char]]
-> Data.Functor.Const.Const (Data.Monoid.First Int) [Item [Char]]
Actual type: (Int
-> Data.Functor.Const.Const (Data.Monoid.First Int) Int)
-> Item a0
-> Data.Functor.Const.Const (Data.Monoid.First Int) (Item a0)
• In the second argument of ‘(.)’, namely ‘itemFreqL’
In the second argument of ‘(.)’, namely ‘_Just . itemFreqL’
In the second argument of ‘(.)’, namely
‘at "AA" . _Just . itemFreqL’
config ^? (configContinuationsL . at "AA" . _Just . itemFreqL) `shouldBe` Just 1
and spec of how I'm testing:
spec :: Spec
spec = do
describe "Markov chain configuration" $ do
it "Adding new starting element to empty configuration creates item with frequency of 1" $ do
let config = addElement Nothing "AA" emptyConfig
config ^? (configStartsL . ix 0 . itemFreqL) `shouldBe` Just 1
config ^? (configStartsL . ix 0 . itemItemL . _Just) `shouldBe` Just "AA"
it "Adding same element twice to empty configuration creates item with frequency of 2" $ do
let config = addElement Nothing "AA" $
addElement Nothing "AA" emptyConfig
config ^? (configStartsL . ix 0 . itemFreqL) `shouldBe` Just 2
config ^? (configStartsL . ix 0 . itemItemL . _Just) `shouldBe` Just "AA"
it "Adding new continuation creates item with frequency of 1" $ do
let config = addElement (Just "AA") "BB" $
addElement Nothing "AA" emptyConfig
config ^? (configContinuationsL . at "AA" . _Just . itemFreqL) `shouldBe` Just 1