簡體   English   中英

無法將小型C#“Random String”函數轉換為Haskell

[英]Trouble translating small C# “Random String” function to Haskell

我在我的公司代碼庫中看到了以下代碼,並且自己想到“該死的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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM