Haskell在检查两个贴图的值并进行更改后,将它们组合成一个贴图

Haskell在检查两个贴图的值并进行更改后,将它们组合成一个贴图,haskell,Haskell,我有两个映射,例如:[(“a”,“b”)]和[(“b”,“c”),(“b”,“d”)],其中输出映射将具有(x,z)值,如果存在这样的y,例如映射a中的(x,y)和映射b中的(y,z) 因此,对于上述地图[(“a”、“b”)]和[(“b”、“c”),(“b”、“d”)]的输出应为[(“a”、“c”),(“a”、“d”)] 如何做到这一点?您可以将列表与b中匹配的所有元素绑定(flatmap): map1::[(字符串,字符串)] map1=[(“a”、“b”)] map2::[(字符串,字符串)

我有两个映射,例如:
[(“a”,“b”)]
[(“b”,“c”),(“b”,“d”)]
,其中输出映射将具有(x,z)值,如果存在这样的y,例如映射a中的(x,y)和映射b中的(y,z)

因此,对于上述地图
[(“a”、“b”)]
[(“b”、“c”),(“b”、“d”)]
的输出应为
[(“a”、“c”),(“a”、“d”)]

如何做到这一点?

您可以将列表与
b
中匹配的所有元素绑定(flatmap):

map1::[(字符串,字符串)]
map1=[(“a”、“b”)]
map2::[(字符串,字符串)]
map2=[(“b”,“c”),(“b”,“d”)]
组合映射::(等式b)=>[(a,b)]->[(b,c)]->[(a,c)]
组合映射m1 m2=m1>>=\(a,b)->
地图(\(c,d)->(a,d))
. 过滤器(\(c,d)->b==c)
$m2
main::IO()
main=print$combineMaps map1 map2--[(“a”、“c”),(“a”、“d”)]
您可以将列表与
b
中匹配的所有元素绑定(flatmap):

map1::[(字符串,字符串)]
map1=[(“a”、“b”)]
map2::[(字符串,字符串)]
map2=[(“b”,“c”),(“b”,“d”)]
组合映射::(等式b)=>[(a,b)]->[(b,c)]->[(a,c)]
组合映射m1 m2=m1>>=\(a,b)->
地图(\(c,d)->(a,d))
. 过滤器(\(c,d)->b==c)
$m2
main::IO()
main=print$combineMaps map1 map2--[(“a”、“c”),(“a”、“d”)]

这个问题描述可以从字面上翻译成一个列表:

-- The type of association lists
type Assoc a b = [(a, b)]

-- Equivalent to ‘(Eq y) => [(x, y)] -> [(y, z)] -> [(x, z)]’
composeAssocs :: (Eq y) => Assoc x y -> Assoc y z -> Assoc x z

composeAssocs xy yz =  -- The composition of two associations
  [ (x, z)             -- …is the set of all pairs (x, z)
  | (x, y) <- xy       -- …for each pair (x, y) in the first
  , (y', z) <- yz      -- …and each pair (y', z) in the second
  , y == y'            -- …where y = y'.
  ]
但是请注意,这不是很有效:输入列表的长度需要O(n2)个时间,因为对于第一个关联的每个元素,将检查第二个关联的每个元素。如果使用更高效的表示法,如
Data.Map
,则可以获得更好的性能,例如:

import Data.Map (Map)
import Data.Set (Map)
import qualified Data.Map as Map
import qualified Data.Set as Set

type Relation a b = Map a (Set b)

composeRelations :: (Ord x, Ord y, Ord z) => Relation x y -> Relation y z -> Relation x z
composeRelations xy yz = Map.fromListWith Set.union
  [ (x, zs)
  | (x, ys) <- Map.toList xy
  , y <- Set.toList ys
  , Just zs <- pure (Map.lookup y yz)
  ]
如果我们使用了
fromList
,以后的查找将覆盖以前的查找:

composeRelationsWrong :: (Ord x, Ord y) => Relation x y -> Relation y z -> Relation x z
composeRelationsWrong xy yz = Map.fromList
  [ (x, zs)
  | (x, ys) <- Map.toList xy
  , y <- Set.toList ys
  , Just zs <- pure (Map.lookup y yz)
  ]

composeRelationsWrong
  (relation [("a", "b"), ("a", "c")])
  (relation [("b", "x"), ("b", "y"), ("c", "z")])
  == relation [("a", "z")]
组合关系错误::(Ord x,Ord y)=>关系x y->关系y z->关系x z
Composer关联错误xy yz=Map.fromList
[(x,zs)

|(x,ys)这个问题描述可以从字面上翻译成列表理解:

-- The type of association lists
type Assoc a b = [(a, b)]

-- Equivalent to ‘(Eq y) => [(x, y)] -> [(y, z)] -> [(x, z)]’
composeAssocs :: (Eq y) => Assoc x y -> Assoc y z -> Assoc x z

composeAssocs xy yz =  -- The composition of two associations
  [ (x, z)             -- …is the set of all pairs (x, z)
  | (x, y) <- xy       -- …for each pair (x, y) in the first
  , (y', z) <- yz      -- …and each pair (y', z) in the second
  , y == y'            -- …where y = y'.
  ]
但是请注意,这不是很有效:输入列表的长度需要O(n2)个时间,因为对于第一个关联的每个元素,将检查第二个关联的每个元素。如果使用更有效的表示形式,例如
Data.Map
,则可以获得更好的性能,例如:

import Data.Map (Map)
import Data.Set (Map)
import qualified Data.Map as Map
import qualified Data.Set as Set

type Relation a b = Map a (Set b)

composeRelations :: (Ord x, Ord y, Ord z) => Relation x y -> Relation y z -> Relation x z
composeRelations xy yz = Map.fromListWith Set.union
  [ (x, zs)
  | (x, ys) <- Map.toList xy
  , y <- Set.toList ys
  , Just zs <- pure (Map.lookup y yz)
  ]
如果我们使用了
fromList
,以后的查找将覆盖以前的查找:

composeRelationsWrong :: (Ord x, Ord y) => Relation x y -> Relation y z -> Relation x z
composeRelationsWrong xy yz = Map.fromList
  [ (x, zs)
  | (x, ys) <- Map.toList xy
  , y <- Set.toList ys
  , Just zs <- pure (Map.lookup y yz)
  ]

composeRelationsWrong
  (relation [("a", "b"), ("a", "c")])
  (relation [("b", "x"), ("b", "y"), ("c", "z")])
  == relation [("a", "z")]
组合关系错误::(Ord x,Ord y)=>关系x y->关系y z->关系x z
Composer关联错误xy yz=Map.fromList
[(x,zs)

|(x,ys)当然你应该有更像
composeMaps::combineMaps::Eq b=>[(b,c)]->[(a,b)]->[(a,c)]
,它更一般,也更容易理解。我无法立即判断代码中的合成方式。然后在它上运行
nub
。当然你应该有更像
composeMaps::combineMaps::Eq b=>[(b,c)]->[(a,b)]->[(a,c)]
,它更一般,也更容易理解。我无法立即判断代码中的合成方式。然后在代码上运行
nub
。您已经知道列表理解吗?尝试将where子句转换为列表理解!您已经知道列表理解吗?尝试转换where子句into一份清单!