0

我正在尝试为“制表”编写一个定义,该函数生成给定 Map 中与给定可折叠集合中的键相对应的值的幺半群摘要。

这是我的代码:

module Foldables where

import Prelude hiding (Applicative(..), any, concat)
import Data.Foldable
import Data.Semigroup

import qualified Data.Map as Map
import Data.Map (Map)
import Data.Map.Append (AppendMap(..))
import Data.List (intersperse)
import Data.Maybe (maybe)
import Data.Monoid (Any(..), Sum(..))
import GHC.Generics (Generic)

tabulate :: (Ord k, Foldable f, Monoid a) => (v -> a) -> Map k v -> f k -> a
tabulate t m = foldMap (tabulate . k v)

我收到此错误:

src/Foldables.lhs:295:27: error:
    • Data constructor not in scope: Tabulate :: b0 -> a
    • Perhaps you meant variable ‘tabulate’ (line 295)

src/Foldables.lhs:295:38: error:
    Variable not in scope: k :: t0 -> k -> b0

除了第二行括号中的内容外,请不要更改任何内容

更新:我想我更接近于理解这一点。这是我的新代码。我意识到它是不完整的,但它至少可以编译。

tabulate :: (Ord k, Foldable f, Monoid a) => (v -> a) -> Map k v -> f k -> a
tabulate t m = foldMap (\x -> mempty maybe [m] maybe map [t])

现在它没有通过阴谋集团测试:

   Falsified (after 2 tests):
     <fun>
     fromList [(False,'\DC4'),(True,'\1054302')]
     [True,True]

不管我做什么似乎都有一些变化

我假设如果 tabulate 的第三个参数不是空的,我需要的是某种条件?

4

1 回答 1

1

这是一个提示(这是一个没有 的解决方案foldMap,我认为这是问题的对象):

如果我理解正确,你想写下这样的内容:

tabulate :: (Ord k, Foldable t, Monoid a) => (v -> a) -> Map k v -> t k -> a
tabulate t m ks = let
                    c k x = (t <$> Data.Map.Strict.lookup k m) <> x
                  in case Prelude.foldr c Nothing ks of
                          Just s  -> s
                          Nothing -> mempty

ks(顺便说一下,解决方案foldMap不需要这个参数 - 它将被删除,正如你在帖子中想要的那样)与地图(m)的键的交集为空(也就是说,只有Nothings被收集)。

mappend在其他情况下,我们只是用一些东西折叠键的容器,类似于Maybe- 它首先尝试在地图中查找给定的键。如果成功,它将结果放入Just然后fmap将转换t(给我们一个幺半群)放入其中。如果没有,则返回Nothing. 在 s 的mappend-sequence 中,Maybe所有Nothings 都被丢弃,s 内的结果Just与 s 连接mappend。请参阅<>for Maybe( <>isSemigroup的方法的定义,它是mappendas MonoidisSemigroup的子类的基础):

-- | @since 4.9.0.0
instance Semigroup a => Semigroup (Maybe a) where
    Nothing <> b       = b
    a       <> Nothing = a
    Just a  <> Just b  = Just (a <> b)
    ...

我的解决方案foldMap

tabulate :: (Ord k, Foldable t, Monoid a) => (v -> a) -> Map k v -> t k -> a
tabulate t m = foldMap (\ k -> maybe mempty t (Data.Map.Strict.lookup k m))

它执行以下操作:函数参数foldMap采用 key k。如果它不在地图中,则返回mempty. 否则 - 它返回t x,得到Just x什么lookup

于 2020-08-17T11:22:24.860 回答