如果我有两个列表,我想定义元素之间的位置相等(在特定意义上)。例如,如果:在haskell列表中的位置相等
k = [[3,1,2,4],[1,4,2,3],[1,3,4,2]]
s = [["a","b","c","d"],["d","a","c","b"],["c","b","a","d"],["d","b","c","a"]]
,我想可以说2 ∼ "c"
的功能和返回的所有元组,其中2
和c
份额在列表中的相同位置。
res= [([3,1,2,4],["a","b","c","d"])
,([3,1,2,4],["d","a","c","b"])
,([3,1,2,4],["d","b","c","a"])
,([1,4,2,3],["a","b","c","d"])
,([1,4,2,3],["d","a","c","b"])
,([1,4,2,3],["d","b","c","a"])
]
像这样的事情会在其他一些语言两个回路的事,但我花了一天时间尝试写在Haskell这个功能更好的一部分。我目前的尝试:
eqElem i1 (l1:ls1) i2 (l2:ls2) = helper1 i1 l1 i2 l2 0 where
helper1 i1 (p:ps) i2 l2 ctr1
| i1 == p = helper2 i2 l2 ctr1 0
| otherwise = helper1 i1 ps i2 l2 (ctr1+1)
helper2 i2 (p:ps) ctr1 ctr2
| i2==p && ctr1==ctr2 = (l1,l2):(eqElem i1 (l1:ls1) i2 ls2)
| otherwise = helper2 i2 ps ctr1 (ctr2+1)
helper2 i2 [] ctr1 ctr2 = eqElem i1 ls1 i2 (l2:ls2)
eqElem i1 [] i2 _ = []
眼下这给:
*Main Lib> eqElem 2 k "c" s
[([3,1,2,4],["a","b","c","d"]),([3,1,2,4],["d","a","c","b"])]
这是只有大约一半的权利;如果我坚持下去,我可能会做得对,但我只是想确保我不会重新发明轮子或什么。
那么...什么是地道的Haskell方式来做到这一点?有一个吗?我觉得我迫使Haskell成为势在必行,并且必须有一些更高阶的函数或方法来完成这个任务。
的大问题是我不知道前手名单。它们可以是任意数据类型,不同长度和/或(嵌套)深度。
将它们从用户输入解析为REPL并存储在ADT中,该ADT最多可以为Functor
,Monad
和Applicative
。列表理解需要Alternative
和MonadPlus
,但不能做那些,因为然后分类理论会发疯。
每个列表中的元素是否唯一唯一? – immibis
是的,我正在看的情况。 – ITA