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

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

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

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

Q&A

解決済

1回答

682閲覧

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

Sme

総合スコア30

Haskell

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

0グッド

0クリップ

投稿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の中身であるものとする.
追伸:今最終的に目標とするのはブラックジャックですが,成否問わず学習を目的に作成しようと試みています.

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

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

その通りです。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

総合スコア2035

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Sme

2022/06/13 12:58

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問