c# - 将小 C# "Random String"函数转换为 Haskell 时遇到问题

标签 c# string linq haskell random

我在我公司的代码库中看到了以下代码,我心想“该死的,这是 linq 的一个很好的行,我想把它翻译成 Haskell,看看它在实际的函数式语言中是什么样子的”

static Random random = new Random();
static string RandomString(int length)
{
    const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    return new string(Enumerable.Repeat(chars, length)
                                .Select(s => s[random.Next(s.Length)])
                                .ToArray());
}

但是,由于用这种语言生成随机数非常尴尬,所以我在将其简明直接地翻译成 Haskell 时遇到了一些麻烦。

我考虑了几种方法。 C# 代码的最直接翻译只生成一个随机索引,然后使用它代替 random.Next(s.Length)。但是我需要生成多个索引,而不是一个。

然后我考虑做一个 IO Int 随机数操作列表,但我无法弄清楚如何将 IO 操作列表转换为实际操作随机数。

因此,与 C# 相比,我最终编写的 Haskell 代码看起来非常复杂(在这种情况下我没有想到),而且我什至还没有让它工作。

我的问题是,C# 到 Haskell 的自然翻译是什么?或者更一般地说,您将如何在 Haskell 中生成指定长度的随机字符串(因为这种 C# 方式似乎不能很好地转换为 Haskell)?

注意:我主要感兴趣的是在 Haskell 中生成随机字符串的算法是什么样的。我对任何为我完成这项工作的标准库都不感兴趣

最佳答案

Haskell 的自然翻译涉及某种IO(因为您需要随机性)。由于您实质上是在尝试执行选择字符 n 次的操作,因此您想使用 replicateM .然后,要获取范围内的随机数,您可以使用 randomRIO .

import Control.Monad (replicateM)
import System.Random (randomRIO)

randomString :: Int -> IO String
randomString n = replicateM n (do r <- randomRIO (0,m); pure (chars !! r))
  where
    chars = ['A'..'Z'] ++ ['0'..'9']
    m = length chars

这有点复杂,因为您需要一个仅包含特定范围内的字符的字符串。否则,您将有一个单行代码:randomString n = replicateM n randomIO


也就是说,更忠实的翻译会使用 conduit .我不会包括导入和语言编译指示(因为它们有点痛苦)。这看起来更像您在 C# 中编写的内容:

randomString' :: Int -> IO String
randomString' n = runConduit $ replicate n chars
                            .| mapM (\cs -> do r <- randomRIO (0,m); pure (cs !! r))
                            .| sinkList
  where
    chars = ['A'..'Z'] ++ ['0'..'9']
    m = length chars

关于c# - 将小 C# "Random String"函数转换为 Haskell 时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40836139/

相关文章:

c# - Linq 中的WhereSelectArrayIterator 是什么?

c# - “无法从用法中推断出类型参数”

java - 为什么 String.equals 对于不相同(但相等)的 String 对象要慢得多?

python - 查找字符串中不存在的文本

c# - 如何将此 Linq 查询语法转换为方法语法?

c# - 如何检查字符串数组中的所有字符串是否都是数字?

c# - 可以通过 $http 但不能通过 ngResource 调用 WCF 服务

c# - 解压缩来自 WebClient 的 gzip 响应

c# - 在 .NET 应用程序中传递 XML 的最佳方式是什么?

html - CSS break-word 首先使用符号