質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
Haskell

Haskellは高い機能性をもった関数型プログラミング言語で、他の手続き型プログラミング言語では難しいとされている関数でも容易に行うことができます。強い静的型付け、遅延評価などに対応しています。

解決済

乱数モナドの利用に関して対話実行では動作するのにインタプリタとしてはエラーが出る.

Sme
Sme

総合スコア30

Haskell

Haskellは高い機能性をもった関数型プログラミング言語で、他の手続き型プログラミング言語では難しいとされている関数でも容易に行うことができます。強い静的型付け、遅延評価などに対応しています。

1回答

0グッド

0クリップ

391閲覧

投稿2022/06/12 14:38

Haskellは先週程度にインストールした初心者です.
http://www.nct9.ne.jp/m_hiroi/func/haskell26.html 等のサイトを参考に,乱数モナドを用いて何かしようと考え,一旦次のコードを実行しようとしました.

Haskell

1import System.Random 2r = getStdRandom(randomR(1,4)) 3main = r >>= print

しかしながら,次のエラーが出力されました.

txt

1 2bj2.hs:2:18: error: 3 • Ambiguous type variable ‘a0’ arising from a use of ‘randomR’ 4 prevents the constraint ‘(Random a0)’ from being solved. 5 Relevant bindings include r :: IO a0 (bound at bj2.hs:2:1) 6 Probable fix: use a type annotation to specify what ‘a0’ should be. 7 These potential instances exist: 8 instance Random Integer -- Defined in ‘System.Random’ 9 instance (Random a, Random b) => Random (a, b) 10 -- Defined in ‘System.Random’ 11 instance (Random a, Random b, Random c) => Random (a, b, c) 12 -- Defined in ‘System.Random’ 13 ...plus 10 others 14 ...plus 30 instances involving out-of-scope types 15 (use -fprint-potential-instances to see them all) 16 • In the first argument of ‘getStdRandom’, namely 17 ‘(randomR (1, 4))’ 18 In the expression: getStdRandom (randomR (1, 4)) 19 In an equation for ‘r’: r = getStdRandom (randomR (1, 4)) 20 | 212 | r = getStdRandom(randomR(1,4)) 22 | ^^^^^^^^^^^^ 23 24bj2.hs:2:26: error: 25 • Ambiguous type variable ‘a0’ arising from the literal ‘1’ 26 prevents the constraint ‘(Num a0)’ from being solved. 27 Relevant bindings include r :: IO a0 (bound at bj2.hs:2:1) 28 Probable fix: use a type annotation to specify what ‘a0’ should be. 29 These potential instances exist: 30 instance Num Integer -- Defined in ‘GHC.Num’ 31 instance Num Double -- Defined in ‘GHC.Float’ 32 instance Num Float -- Defined in ‘GHC.Float’ 33 ...plus two others 34 ...plus 35 instances involving out-of-scope types 35 (use -fprint-potential-instances to see them all) 36 • In the expression: 1 37 In the first argument of ‘randomR’, namely ‘(1, 4)’ 38 In the first argument of ‘getStdRandom’, namely ‘(randomR (1, 4))’ 39 | 402 | r = getStdRandom(randomR(1,4)) 41 | ^ 42 43bj2.hs:3:14: error: 44 • Ambiguous type variable ‘a0’ arising from a use of ‘print’ 45 prevents the constraint ‘(Show a0)’ from being solved. 46 Probable fix: use a type annotation to specify what ‘a0’ should be. 47 These potential instances exist: 48 instance Show Ordering -- Defined in ‘GHC.Show’ 49 instance Show StdGen -- Defined in ‘System.Random.Internal’ 50 instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’ 51 ...plus 24 others 52 ...plus 48 instances involving out-of-scope types 53 (use -fprint-potential-instances to see them all) 54 • In the second argument of ‘(>>=)’, namely ‘print’ 55 In the expression: r >>= print 56 In an equation for ‘main’: main = r >>= print 57 | 583 | main = r >>= print 59 |

尚,ghciでは次の結果が得られています.

Haskell

1ghci> import System.Random 2ghci> r = getStdRandom(randomR(1,4)) 3ghci> main = r >>= print 4ghci> main 54

このコードでインタプリタとして実行した時と,対話で実行した時に差が発生する理屈が分かりません.
エラーコードを翻訳した限り型注釈が必要と書いてあるように見えますが,どこに型注釈を入れるべきなのか,そしてモナドの型注釈はどのように記述するべきなのかが分かりません.
また,少々話が逸れますが,主にこちらのサイト(https://minoki.github.io/ks-material/haskell/ )を参考に入門を試みていますが,データ型とパターンマッチ以降の題材に関して良く理解出来ていないと考えているので,参考にしやすいサイト等々ありましたらお教えいただけますと幸いです.
実行環境表示
$stack --version
Version 2.7.5, Git revision ba147e6f59b2da75b1beb98b1888cce97f7032b1 x86_64 hpack-0.34.4
$cat /etc/debian_version
11.2
上部実行コマンド $stack runghc bj2,hs 2> error.txt
下部実行コマンド $stack ghci
但し上部のファイル名をbj2.hsとし,エラー出力として示したものはerror.txtの中身であるものとする.
追伸:今最終的に目標とするのはブラックジャックですが,成否問わず学習を目的に作成しようと試みています.

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答1

1

ベストアンサー

エラーコードを翻訳した限り型注釈が必要と書いてあるように見えますが,どこに型注釈を入れるべきなのか,そしてモナドの型注釈はどのように記述するべきなのかが分かりません

その通りです。randomR関数は以下のようにRandom型クラスの任意の型と乱数ジェネレーターの任意の型を返すことができるので、どの型が欲しいのかを型注釈で教えてあげる必要があります。

haskell

1-- randomRの型 2ghci> import System.Random 3ghci> :t randomR 4randomR :: (Random a, RandomGen g) => (a, a) -> g -> (a, g)

型注釈は以下のように式の後ろに書いたり、(ソースファイルの)関数の上に書いたりできます。IOモナドの場合はIO 型のように書きます。

haskell

1-- 整数型 2ghci> getStdRandom (randomR (1, 4)) :: IO Int 33 4 5-- 浮動小数点型 6ghci> getStdRandom (randomR (1, 4)) :: IO Double 71.5531236429846564

ソースファイルでは各関数の上に型注釈を付けるのが一般的ですので、以下のようにするといいでしょう。

haskell

1import System.Random 2 3r :: IO Int 4r = getStdRandom (randomR (1, 4)) 5 6main :: IO () 7main = r >>= print

これでエラーが解消します。

なお、IO ()()は空のタプルで、ユニットと読みます。値がない(意味のある情報がない)ことを示します。

このコードでインタプリタとして実行した時と,対話で実行した時に差が発生する理屈が分かりません.

ghciで対話形式で実行する際に、いちいち型注釈を付けるのは面倒なので、Haskellのtype defaultingという仕組みが使われています。default (デフォルト型1, デフォルト型2, ... ) のように設定します。

haskell

1ghci> default (Double) 2ghci> getStdRandom (randomR (1, 4)) 33.5087915111895005 4ghci> default (Integer) 5ghci> getStdRandom (randomR (1, 4)) 63

type defaultingについては以下で解説されています。

主にこちらのサイトを参考に入門を試みていますが,データ型とパターンマッチ以降の題材に関して良く理解出来ていないと考えているので,参考にしやすいサイト等々ありましたらお教えいただけますと幸いです.

10年ちょっと前の話ですが、わたし自身は「Learn you a Haskell for Great Good!」という英語のサイトで学習しました。その後、そのサイトをベースにした同名の書籍が出版され、和訳本も出版されています。

Haskell Stackなどのツールがなかった時代の本なので、そういう情報は載ってないのですが、基本を学ぶには今でもいい本だと思います。

投稿2022/06/13 11:52

編集2022/06/13 11:54
tatsuya6502

総合スコア1998

Sme👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

Sme

2022/06/13 12:58

有難うございました.Learn you a Haskell for Great Good!で学習し直します.

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Haskell

Haskellは高い機能性をもった関数型プログラミング言語で、他の手続き型プログラミング言語では難しいとされている関数でも容易に行うことができます。強い静的型付け、遅延評価などに対応しています。