在Haskell中更改类型

时间:2016-09-18 22:24:02

标签: haskell

我希望构造一个只包含字母字符的随机字符串。这是我到目前为止的代码:

letters :: String
letters = "abcdefghijklmnopqrstuvwxyz"

{- | Generates any lower case alpha character.
-}
lowerAlpha :: Gen Char
lowerAlpha = oneof (map return letters)

getString :: Int -> String
getString 0 = []
getString n = lowerAlpha : getString (n - 1)

getString在1到25之间传递一个随机Int。因为lowerAlpha返回Gen Char,getString不会工作,因为它需要一个Char来构建一个String。有没有办法将Gen String更改为String?这是出现问题的代码行 - getString n = lowerAlpha : getString (n - 1)

3 个答案:

答案 0 :(得分:7)

  

有没有办法将Uncaught Error: Invariant Violation: _registerComponent(...): Target container is not a DOM element. 更改为Gen String

不,强调不是。出于某种原因,来自其他编程语言的人似乎总是认为“他们都是字符串类型,所以他们肯定是可以转换的”。不! String完全与Gen String完全不同。后者只是一个普通的数据值 - 一个字符列表。但是String是一个生成器,一个生成字符串的动作。假设这可以转换为字符串就像假设牛可以转换成牛奶瓶一样。

正确的事情当然是Gen String也有getString类型,因为生成字符串就是它的作用。

Gen

问题是如何实施。好吧,这是猜测,因为你没有明确指出getString :: Int -> Gen String 是什么,但Haskell中的这种类型构造函数通常是applicative functors。这允许你写

Gen

正如加莱所说,这也可以缩短为

getString 0 = pure []
getString n = (:) <$> lowerAlpha <*> getString (n - 1)

答案 1 :(得分:3)

也许您正在寻找vectorOf,即:

import Test.QuickCheck

getString :: Int -> Gen String
getString n = vectorOf n lowerAlpha

要实际生成随机字符串,您可以使用generate(需要IO-monad):

main = do
  generate (getString 25) >>= putStrLn

或仅来自GHCI repl:

ghci> generate (getString 25)
"siebrxrlvuuxdvhqwcfykqwdc"
ghci> generate (getString 3)
"rcv"

答案 2 :(得分:1)

感谢您的协助。这就是我提出的。效果很好。 str <- listOf (choose ('a','z'))