哈斯克尔,48岁
f=(!!)(sequence=<<(tail$iterate(['A'..'Z']:)[]))
少打高尔夫球:
f n = (concatMap sequence $ tail $ iterate (['A'..'Z'] :) []) !! n
说明
Haskell的sequence
组合器获取动作列表并执行它们,并在列表中返回每个动作的结果。例如:
sequence [getChar, getChar, getChar]
等效于:
do
a <- getChar
b <- getChar
c <- getChar
return [a,b,c]
在Haskell中,将动作视为值,并使用>>=
(绑定)和return
原语将动作粘合在一起。如果任何类型通过拥有Monad实例来实现这些运算符,则可以是“操作” 。
顺便说一句,列表类型具有monad实例。例如:
do
a <- [1,2,3]
b <- [4,5,6]
return (a,b)
这等于[(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)]
。请注意,列表理解非常相似:
[(a,b) | a <- [1,2,3], b <- [4,5,6]]
由于列表是一种“动作”,因此我们可以将其sequence
与列表一起使用。以上可以表示为:
sequence [[1,2,3],[4,5,6]]
因此,sequence
免费为我们提供组合!
因此,要构建列表:
["A","B"..."Z","AA","AB"]
我只需要建立要传递的清单 sequence
[['A'..'Z'],['A'..'Z','A'..'Z'],...]
然后使用concatMap
既应用sequence
到列表,又连接结果列表。巧合的concatMap
是=<<
列表的功能,因此list monad也让我在这里剃了几个字符。