mapM 如何与 Haskell 中的 const 函数一起工作?

Aty*_*afi 5 monads combinations haskell constants map-function

由于我一直在寻找优化我一直在制作的密码破解程序的方法,我遇到了一个列表中所有可能的字符组合的更短的实现,它使用了这个函数:

mapM (const xs) [1..n]
Run Code Online (Sandbox Code Playgroud)

哪里xs可以是可用的字符,以及n所需单词的长度。所以

mapM (const "abcd") [1..4]
Run Code Online (Sandbox Code Playgroud)

会输出一个列表["aaaa","aaab","aaac","aaad","aaba","aabb"..]等等。只有长度对右边的列表很重要,我可以写['f','h','s','e']或任何 4 个元素列表代替。

我可以理解为什么列表无关紧要,它被传递给了一个const函数。我可以看到const一个列表在技术上满足(a -> m a).

但我的问题是:为什么不是简单的输出["abcd","abcd","abcd","abcd"],或者可能"abcdabcdabcdabcd"?什么是一个const函数做输出给定的字母所有4度字母的变化?

chi*_*chi 6

您可以mapM使用这种直觉来理解:

mapM f [x1, x2, ..., xN]
=
do y1 <- f x1
   y2 <- f x2
   ...
   yN <- f xN
   return [y1, y2, ..., yN]
Run Code Online (Sandbox Code Playgroud)

在你的情况下:

mapM (const "abcd") [1 .. 4]
=
do y1 <- const "abcd" 1
   y2 <- const "abcd" 2
   y3 <- const "abcd" 3
   y4 <- const "abcd" 4
   return [y1, y2, y3, y4]
=
do y1 <- "abcd"
   y2 <- "abcd"
   y3 <- "abcd"
   y4 <- "abcd"
   return [y1, y2, y3, y4]
Run Code Online (Sandbox Code Playgroud)

后者相当于一个列表推导式

[ [y1, y2, y3, y4] | y1<-"abcd", y2<-"abcd", y3<-"abcd", y4<-"abcd"]
Run Code Online (Sandbox Code Playgroud)

这将产生您的输出。