【发布时间】:2021-02-21 14:26:17
【问题描述】:
作为 Haskell 的新手,以惯用的方式思考是一项挑战。我有一份双人名单。我想根据两张地图对二元组成员进行加权,一张指示权重方向,另一张提供权重本身。在下面的代码中,1 表示 dyad 的底部成员接受重量; -1 二元组的最高成员接受重量; 0 两个成员都获得权重。在所有情况下,决定权重和方向的是对偶成员之间的差异
我的问题是,在权重相等的情况下,如何重新使用顶部和底部权重分配的定义?到目前为止,我咨询过的每个消息来源似乎都表明守卫只能有一个结果——我怀疑这是正确的 Haskell 方式......
allocateWeight :: [[Integer]] -> (Integer, Integer, Maybe Double)
allocateWeight [x, y]
|direction <= Just 1 = assignBottom
|direction <= Just (-1) = assignTop
|direction <= Just 0 = (?? assignBottom and assignTop ??)
where diff = (abs(x!!1 - y!!1))
direction = Map.lookup diff getWeightDirection
weight = Map.lookup diff schemaCAT
assignBottom = (head x, last x, weight)
assignTop = (head y, last y, weight)
好的,我已被要求进一步澄清。我会削减非必需品,因为它们只会使问题变得模糊。
第 1 阶段:从值列表开始,例如:[6, 3, 8, 11, 2]:值限制在 1 到 12 之间。
第 2 阶段:将它们排列成对子:[(6,3),(6,8), (6,11), (6,2), (3, 8), (3, 11),(3 , 2),(8, 11)(8, 2),(11,2)]
Stage 3:获取每对的绝对差:[(3),(2),(5),(4),(5),(8),(1),(3),(6) ,(9)]
第4阶段:根据他们之间的差异,每个对子中的一个成员(6个除外)将获得权重;这是在以下地图中预先确定的:
getWeightDiretion :: Map.Map Integer Integer -- determine weight direction
getWeightDirection = Map.fromList $
[(1, -1),
(2, -1),
(3, 1),
(4, 1),
(5, -1),
(6, 0),
(7, 1),
(8, -1),
(9, -1),
(10, 1),
(11, 1),
(12, 1))]
如前所述,如果 map lookup 的值为 1,则权重到底部; -1 到顶部。问题是,当查询键为 6 时, 个二元组成员的权重均不大于另一个:也就是说,它们的权重均等。权重也是通过在此地图中查找键来预先确定的:
schemaCAT :: Map.Map Integer Double --Cross-At-Tail weighting scheme
schemaCAT = Map.fromList $
[(12, 0.985),
(11, -0.7),
(10, 0.2),
(9, 0.4),
(8, 0.6),
(7, 0.9),
(6, 0.08),
(5, 0.8),
(4, 0.7),
(3, 0.5),
(2, 0.1),
(1, -0.8),
(999, 0.25)]
allocateWeights 函数的输入格式为 [[(-1, 6), (0, 3)], [.... 其中每个子列表中每个元组的第一个成员是转置因子- 这里不相关;第二个是排列对之一。输入中的每个子列表代表一个排列。 allocateWeights 函数直接对每个子列表中每个元组的 x!!1 进行操作。
应用上述内容后,我应该得到一个元组列表 [(-1, 3, 0.5)....] 第二个元组成员是接收权重的元组成员,第三个是权重本身(我将省略元组的第一个成员是什么并不重要。与键 999 相同,这是一个特殊情况)。
据我了解,我有两个问题。首先,maps 返回 Maybes 并且在守卫中使用这些值是有问题的,其次,是在守卫中的表达式右侧使用两个定义的问题。仍在为“Justs”和“Maybes”而苦苦挣扎:(
THX....
【问题讨论】:
-
您可以返回一个包含两个项目的列表,如果总是有两个结果,则可以返回一个 2 元组。
-
你的第二个和第三个后卫永远不会匹配,因为如果方向是
-
我不清楚你在这里想要什么样的行为。请举几个例子。
-
如何以非惯用方式编写结果,即不尝试重用
assignBottom和assignTop? -
守卫可以返回任何东西,只要每个守卫都返回相同类型的值。
(head x, last x, weight)和(head y, last y, weight)的组合应该是什么样子?
标签: haskell