首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用Haskell的随机元素网格

使用Haskell的随机元素网格
EN

Stack Overflow用户
提问于 2019-05-22 18:50:55
回答 1查看 156关注 0票数 2

完全没有使用Haskell的经验,我需要想出一个等同于Python的代码:

代码语言:javascript
复制
from random import choice, sample

def random_subset():
    return tuple(sample(('N', 'S', 'W', 'E'), choice((1, 2, 3, 4))))

def form_grid(n):
    return [[random_subset() for _ in range(n)] for _ in range(n)]

form_grid(10)

它会产生类似下面这样的结果:

代码语言:javascript
复制
N     ESWN  SNEW  NSE   EWSN  E     ENSW  N     NSWE  WES   
NE    WNS   SWEN  EWN   ENWS  WEN   WS    W     ENSW  NW    
WENS  NWE   SNEW  ES    E     S     ES    SENW  EW    WEN   
NSE   NE    WNE   NEWS  SNE   W     SWNE  NSWE  SNEW  EN    
S     SNW   WNES  S     WESN  E     ES    N     ESN   ES    
SWEN  S     WSNE  NEWS  WESN  E     S     SE    E     N     
NEW   S     NEW   WS    W     EN    N     NWS   E     WENS  
WN    NWE   S     SEW   NESW  EWSN  WENS  ES    NWS   WN    
W     NWE   N     N     ES    E     E     WN    SWNE  NES   
WENS  NWE   NW    WESN  SW    NES   ENWS  SE    N     SWNE 

看在上帝的份上,我无法理解Haskell的IO概念(尤其是随机性)。我能想到的最好的结果是:

代码语言:javascript
复制
import Data.Random hiding (shuffle, sample)
import Data.Random.Source.Std
import Data.Random.Extras

randSubset :: IO [Char]
randSubset = do
    len <- runRVar (choice [1..4]) StdRandom :: IO Int
    subset <- runRVar (sample len ['N', 'S', 'W', 'E']) StdRandom :: IO [Char]
    return subset

formGrid :: Int -> [[IO [Char]]]
formGrid n = [[subset | _ <- [0..(n - 1)], subset <- randSubset] | _ <- [0..(n - 1)]]

仍然没有做到这一点:

代码语言:javascript
复制
error:
    * Couldn't match expected type `[IO [Char]]'
                  with actual type `IO [Char]'
    * In the expression: randSubset
      In a stmt of a list comprehension: subset <- randSubset
      In the expression:
        [subset | _ <- [0 .. (n - 1)], subset <- randSubset]
   |
12 | formGrid n = [[subset | _ <- [0..(n - 1)], subset <- randSubset] | _ <- [0..(n - 1)]]
   |                                                      ^^^^^^^^^^

快速搜索谷歌并没有多大帮助-我可能没有使用最准确的关键字来解决我面临的这个问题。随意更改并期待最好的结果是非常令人沮丧的,但我真的既没有时间也没有精力去深入研究Haskell (尽管这是一种耻辱),所以现在,我希望有人能给我指出这段代码的错误之处。

EN

回答 1

Stack Overflow用户

发布于 2019-05-22 20:17:44

为了补充Willem的回答,我还要补充一句,您的randSubset看起来相当复杂。这里有一个更简单的选择

代码语言:javascript
复制
randSubset :: IO String
randSubset = do
  n <- sample (Uniform 1 4)        -- choose how many elements
  sample (shuffleNofM n 4 "NSWE")  -- take that many elements

(顺便说一句,这是来自Data.Randomsample )

您应该检查这确实是子集的预期分布。请注意,这不是一个统一的分布:NNS更有可能(甚至是NSSN的组合)。还要注意的是,相同子集的每个排列都可能发生,因此我们并不是真正地采样“子集”。我不知道您的Python代码使用的是哪个发行版--毕竟它们可能是相同的。

如果你在IO内部工作,我认为如果你使用sample (someDistribution)而不是在较低级别的RVar上工作会更简单。

在此之后,您可以使用replicateM生成网格,如Willem所示。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56255158

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档