功能包括随机性和警卫

时间:2015-10-15 22:36:58

标签: haskell random types

嘿,我只是想创建一个随机返回字符串的函数。 我对Haskell也很陌生,我也想知道这样的显式类型定义是什么样的。

randomSentence
| rando == 1 = "Who should I train at the beginning of Fire Emblem Awakened? "
| rando == 2 = "You rocked the socks of this question, Thank you for your help. Honest."
| rando == 3 = "If the keyboard was playing music while you were helping me, I bet it'd be the sickest bar."
| otherwise == 4 = "You've made the world a better place for contributing. Be proud."
where   rando = randomR (0,4)

3 个答案:

答案 0 :(得分:4)

如果你是Haskell的新手,你可能想要避免使用随机数字,因为它是大多数语言中简单的事情之一,但结果令人惊讶地陡峭哈斯克尔的学习曲线。我推荐这个进展:

  1. 了解如何在Haskell中使用IO类型的基础知识。否则你将完全不知道如何使用随机数生成器。
  2. 当您对此感到满意时,请编写一些程序,使用IO包中的基于System.Random的随机数生成器(这是The Internet's answer正在演示的内容)。
  3. 了解如何使用StateReader等几个monad。
    • 更先进一点:学习如何使用monad变换器。您可以在此时或之后选择解决此问题。
  4. 当您对此感到满意时,您很有可能使用the MonadRandom library,这样可以更方便地使用随机数生成器。
  5. 当您对此感到满意时,您可以尝试此练习:使用Rand编写您自己的库State monad版本。
  6. 这需要一些时间,但是当你完成(5)时,你会理解相当不错的事情,并且大部分知识转移到其他人身上哈斯克尔的事情,而不仅仅是随机数字。

答案 1 :(得分:2)

随机生成器必须从IO检索伪随机数。这意味着您必须在String monad中返回IO

import System.Random                                                                                                                                                              

randomSentence :: IO String                                                                                                                                                       
randomSentence = go <$> randomRIO (1,4)                                                                                                                                           
  where                                                                                                                                                                           
    go :: Int -> String                                                                                                                                                           
    go 1 = "Who should I train at the beginning of Fire Emblem Awakened? "                                                                                                        
    go 2 = "You rocked the socks of this question, Thank you for your help. Honest."                                                                                              
    go 3 = "If the keyboard was playing music while you were helping me, I bet it'd be the sickest bar."                                                                          
    go 4 = "You've made the world a better place for contributing. Be proud."  

https://hackage.haskell.org/package/random-1.1/docs/System-Random.html

答案 2 :(得分:0)

您的代码不能被赋予明智的类型签名,因为它没有多大意义。让我们从头开始,定义一个函数映射消息ID到消息:

message :: Int -> String
message 0 = "Who should I..."
message 1 = "You rocked..."
message 2 = "If the keyboard..."
message _ = "You've made the world..."

我决定从零开始,因为这是更常见的惯例 - 它并不是真的必要。

现在唯一剩下的部分是艰难的:得到一个随机数。有两个步骤:获取随机生成器(包括种子),然后使用该生成器获取随机数和新生成器。如果您使用热门的tf-random软件包,则可以通过执行IO操作newTFGen来获取初始生成器。拥有该生成器g后,您可以使用randomR (0, 3) g同时获取一个随机数和一个新生成器来生成下一个随机数。请注意,如果您不小心重复使用旧的生成器,每次都会得到完全相同的结果。