haskell 使用透镜用于具有螺纹累积器的嵌套折叠

vql8enpb  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(92)

我有这样的代码来转换一些数据:

newtype XXX = XXX
  { xxx :: [ Text ]
  } deriving (Eq, Show)

oldToNew
  :: [XXX] -> [(Int, [(Int, Text)])]
  -> [[(Int, Int, Text)]]
oldToNew xs old                = map    go1          xs
 where
  go1 (XXX eqs)                = foldr  go2      []  eqs
  go2 l                    acc = foldr (go3 l)   acc old
  go3 l (i, w)             acc = foldr (go4 i l) acc w
  go4 idx1 label1 (idx2, label2) acc =
    if label1 == label2
    then (idx1, idx2, label2):acc
    else acc

字符串
注意两件事:
1.它将一个累加器(最初是空的)穿过所有折叠,
1.每个折叠从前一个折叠中拾取一个参数传递到下一个“go”
如何使用控制透镜和/或光学来完成上述操作。
测试用例:

oldToNewSpec :: Spec
oldToNewSpec  =
  it "oldToNew" $
    oldToNew [ XXX ["this", "that", "also"]
             , XXX ["here", "there"] ]

             [ (0, [(4, "this")])
             , (0, [(1, "here")])
             , (1, [(5, "that")])
             , (2, [(2, "also")])
             , (2, [(3, "there")]) ]
    `shouldBe`
    [ [(0,4,"this"),(1,5,"that"),(2,2,"also")]
    , [(0,1,"here"),(2,3,"there")] ]

nr7wwzry

nr7wwzry1#

我不认为你需要透镜来使这个更可读。列表理解应该让你在你需要去的地方没有太多的麻烦。

oldToNew :: [[Text]] -> [(Int, [(Int, Text)]] -> [[(Text, Int, Int)]]
oldToNew tss rs = [[(t, b, e) | t <- ts, (b, te) <- rs, (e, t') <- te, t == t'] | ts <- tss]

字符串
使用适当的数据结构将使事情更有效,并且可能更具可读性。

oldToNew :: Ord k => Map k v -> [[k]] -> [[(k, v)]]
oldToNew kvs = map (concatMap look) where
    look k = case M.lookup k kvs of
        Nothing -> []
        Just v -> [(k, v)]

相关问题