Haskell 无限计数器的无限列表
对于那些思想可疑的人来说,这不是家庭作业,只是好奇 给定一个有限的字母表,是否有可能构造一个由字母表按相反的字母顺序组成的无限长单词列表 i、 e.给定字母Haskell 无限计数器的无限列表,haskell,infinite,Haskell,Infinite,对于那些思想可疑的人来说,这不是家庭作业,只是好奇 给定一个有限的字母表,是否有可能构造一个由字母表按相反的字母顺序组成的无限长单词列表 i、 e.给定字母“ab” 是否可以构建列表: ["aaaaaa...", "baaaaa...", "abaaaa...", "bbaaaa...", "aabaaa...", ...] 其中,…表示扩展到无限长的列表(以及列表列表) 天真的尝试是: counters alphabet = [c:ounter | ounter <- counters
“ab”
是否可以构建列表:
["aaaaaa...", "baaaaa...", "abaaaa...", "bbaaaa...", "aabaaa...", ...]
其中,…
表示扩展到无限长的列表(以及列表列表)
天真的尝试是:
counters alphabet = [c:ounter | ounter <- counters alphabet, c <- alphabet]
并查看输出:
aa
ba
ab
bb
可能不是最有效的解决方案,但至少它是有效的:
counters alphabet = map f [0..]
where f n = let (q, r) = quotRem n (length alphabet) in alphabet !! r : f q
这个级数看起来像是用左边最低有效位编码一个base-N数,所以我们可以用
f
李>
映射到f
到[0..]
重复$head字母添加到列表的每个元素
为什么不
fix
it
ghci> let bar = let foo ~(st:sts) = [c:st | c <- "ab"] ++ foo sts in fix foo
ghci> take 5 . map (take 5) $ bar
["aaaaa","baaaa","abaaa","bbaaa","aabaa"]
take 10 . map (take 5) $ bar
["aaaaa","baaaa","abaaa","bbaaa","aabaa","babaa","abbaa","bbbaa","aaaba","baaba"]
ghci>let bar=let foo~(st:sts)=[c:st | c取5.map(取5)$bar
[“aaaaa”、“baaaa”、“abaaa”、“bbaaa”、“aabaa”]
拿10张地图(拿5张)$bar
[“aaaaa”、“baaaa”、“abaaa”、“bbaaa”、“aabaa”、“babaa”、“abbaa”、“bbbaa”、“aaaba”、“baaba”]
您可能会发现以下方法很有趣/令人困惑:
duplicates s ss = cycle ss : duplicates s (ss >>= \c -> s >> [c])
counters = transpose . join duplicates
这是因为观察到,第一个字母遵循模式“ababab…”
,第二个字母遵循模式“aabbaabbaabb…”
,第三个字母遵循模式“aabbaabbaabbbbb…”
,等等。这是怎么回事
f@(a:as) = a:('b':a):concatMap (\x -> ['a':x,'b':x]) as where a = ['a','a'..]
<> > <代码>(\x>(a):x,'b':x])/<代码>可以写成<代码>应用< <代码> > <代码>([(a ':),('b':]))纯< < /> >如果你认为它更优雅.< /p> 另一个基于丹尼尔思想的版本:
counters = transpose $ map cycle $ iterate (>>= \x -> [x,x]) "ab"
你知道有无数的单词,所以这个列表不会包括所有的单词?是的,但是你在问题中写了“所有无限长的单词”;不是所有的,只有那些由“a”组成的单词从某种意义上说。如果你只对进入
aaa…
的字符串感到满意,那么为什么不直接生成所有的有限字并加上aaa…
?@redxaxder我试过了。有很多特殊情况,因为序列中的所有有限字都是,“a”,“aa”,“aaa”,…
产生相同的无限单词。我没有找到一个合理优雅(少数特殊情况)和合理有效的解决方案(例如,不使用nub
)同时。@redxaxder,很抱歉这么慢。我把有限长度和固定长度混淆了。是的,我明白你的意思了。谢谢。太好了!我开始意识到需要一个惰性模式,因为它不能以其他方式决定结果是否为非空。喜欢它的简单性!从任何形式生成单词的好方法字母表!对于任何想知道的人来说,(>=\x->[x,x])
等于列表的concat.map(\x->[x,x])
。因此复杂性也是最佳的。
f@(a:as) = a:('b':a):concatMap (\x -> ['a':x,'b':x]) as where a = ['a','a'..]
counters = transpose $ map cycle $ iterate (>>= \x -> [x,x]) "ab"