使用镜头阅读时如何解决“无法将类型'Item a0'与'[Item [Char]]'相匹配”的问题

时间:2019-08-25 07:24:11

标签: haskell lens

我正在用Haskell编写markov链生成器,使用加权列表随机选择元素。测试配置时,出现错误“无法将类型'Item a0'与'[Item [Char]]'相匹配”。我怀疑这与以下事实有关:Item已参数化并且类型检查没有意识到configContinuations中的元素具有正确的类型(因此a0[Char]相对。

在添加addElement :: forall a. Ord a => Maybe a -> a -> Config a -> Config a量词之前,我具有签名forall a的函数也存在类似的问题。

但是,如果我将值检查为:config ^? (configContinuationsL . at "AA" . _Just . itemFreqL) `shouldBe` Just 1,则不知道该怎么做。

下面是ConfigItemFrequency和用于操作它们的镜头的定义。

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)))

我应该更改什么,以便强制类型匹配?

编辑:完整的错误消息

• 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

以及我的测试规范:

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

0 个答案:

没有答案