2016-09-18 4 views
0

アルファベットのみの文字列からなるランダムな文字列を作成したいと考えています。これは私がこれまで持っているコードです:それは文字列を構築するためにシャアを期待するようlowerAlphaはゲンチャーgetStringで文句を言わない仕事を返すので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を渡されます。 Gen StringをStringに変更する方法はありますか?これは、問題が発生したコードの行である - getString n = lowerAlpha : getString (n - 1)

+0

もしあなたがそれを[MCVE]にしてください。 「Gen」と「oneof」が何であるかを推測する必要があるときは、ちょっと面倒です。 – leftaroundabout

+1

これは、特にQuickcheck、または一般的なランダム性についての質問ですか? – Michael

+0

'Char'は' Enum'のインスタンスなので 'letters = ['a' .. 'z']'と書くことで小文字をすべて手作業で入力する必要がなくなります。 – chepner

答えて

7

StringGen Stringを変更する方法はありますか?

いいえ、強調しません。何らかの理由で、他のプログラミング言語から来ている人は、「どちらも文字列型であるので、確かに変換可能です」と考えるようです。いいえ! Gen Stringは、Stringとは完全に根本的に異なるものです。後者は単純なデータ値で、文字のリストです。しかし、Gen Stringはジェネレータであり、アクションは文字列を生成します。これは、牛が牛乳瓶に変換することができると仮定した場合のように、これは文字列に変換することができると仮定します。

正しいものはgetStringを生成する文字列であるため、Genタイプを持つことはもちろんです。

getString :: Int -> Gen String 

質問はそれを実装する方法です。さて、Genが何であるかを指定しなかったので推測ですが、Haskellのこのようなタイプのコンストラクタは通常applicative functorsです。それは発言をgallaisとして、あなたは

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

を書くことができ、これも

getString n = replicateM n lowerAlpha 
+1

'replicateM'に言及する価値があります。 – gallais

3

として短く書くことができますおそらく、あなたはすなわち、vectorOfを探しています:

import Test.QuickCheck 

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

実際に生成するにはランダムストリングgenerate(IOモナドが必要):

main = do 
    generate (getString 25) >>= putStrLn 
のGHCi REPLから

またはちょうど:あなたの援助のための

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

感謝。これは私が思いついたものです。うまくいく。 str <- listOf (choose ('a','z'))