Haskell の関数を書くときに型クラス指定をして書く方法の備忘録

この記事は4分で読めます

このサイトは学部では早稲田で物理を, 修士では東大で数学を専攻し, 今も非アカデミックの立場で数学や物理と向き合っている一市民の奮闘の記録です. 運営者情報および運営理念についてはこちらをご覧ください.

中高の数学の復習から専門的な数学・物理までいろいろな情報を発信しています.
中高数学に関しては自然を再現しよう役に立つ中高数学 中高数学お散歩コース
大学数学に関しては現代数学観光ツアーなどの無料の通信講座があります.
その他にも無料の通信講座はこちらのページにまとまっています.
ご興味のある方はぜひお気軽にご登録ください!


Haskell 弱者なので.
元ネタは次の本の演習問題.

何となく Haskell で書き直してみている.
問題の 18.3 について Gist に上げて,
それを実解析 P に質問してみた.

結局 b についての型指定についてはいまだによくわかっていない.
次のコードで次のエラーが出る.

#+BEGIN_SRC haskell :results output
assoc :: (Eq a, Eq b) => a -> [(a, b)] -> Maybe b
assoc _ [] = Nothing
assoc ekimei0 (x:xs) =
if fst x == ekimei0 then Just (snd x)
else assoc ekimei0 xs

main = do
— 実行するとエラーになる:今の腕では解消できない
print $ assoc “後楽園” [] == Nothing
print $ assoc “後楽園” [(“新大塚”, 1.2), (“後楽園”, 1.8)] == Just (1.8)
print $ assoc “池袋” [(“新大塚”, 1.2), (“後楽園”, 1.8)] == Nothing
#+END_SRC

#+RESULTS:

runghc ex18_3_1.hs で実行すると次のエラーがでる.

#+BEGIN_SRC haskell :results silent
ex18_3_1.hs:11:11: error:
• Ambiguous type variable ‘b0’ arising from a use of ‘==’
prevents the constraint ‘(Eq b0)’ from being solved.
Probable fix: use a type annotation to specify what ‘b0’ should be.
These potential instances exist:
instance Eq Ordering — Defined in ‘GHC.Classes’
instance Eq Integer
— Defined in ‘integer-gmp-1.0.0.1:GHC.Integer.Type’
instance Eq a => Eq (Maybe a) — Defined in ‘GHC.Base’
…plus 22 others
…plus 9 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the second argument of ‘($)’, namely
‘assoc “\24460\27005\22290” [] == Nothing’
In a stmt of a ‘do’ block:
print $ assoc “\24460\27005\22290” [] == Nothing
In the expression:
do { print $ assoc “\24460\27005\22290” [] == Nothing;
print
$ assoc
“\24460\27005\22290”
[(“\26032\22823\22618”, 1.2), (“\24460\27005\22290”, 1.8)]
== Just (1.8);
print
$ assoc
“\27744\34955”
[(“\26032\22823\22618”, 1.2), (“\24460\27005\22290”, 1.8)]
== Nothing }
#+END_SRC

バージョンは次の通り.

#+BEGIN_SRC
$ ghci –version
The Glorious Glasgow Haskell Compilation System, version 8.0.1
#+END_SRC

他にも気になることがあったりはしている.
数学の初学者の苦労はわからないことも多くなっているが,
自分自身が適当な分野の初学者になると「こんなところでもつまずく」系事例が
簡単に収集できる.

追記
コメントを頂いた.

[] の型がわからないのでそこから b の型を推論できないからですね。 たとえば ([]::(Fractional a) => [(String, a)]) というふうに型情報を書いておけばいけます。 明示しないとき assoc が返す値の型は Maybe b ということまでしかわかりませんから、 b の型が特定できません。 入力が [] のときに返ってくるのは Nothing ですから b の型は関係なさそうな気もしますが、たとえば Maybe Int の Nothing と Maybe Char の Nothing は (型がことなるので) 比較したりできません。

assoc の型の方でもう少し b の型を制限する、たとえば (Num b) という制限をいれても大丈夫です。

あとで試してみよう.


中高の数学の復習から専門的な数学・物理までいろいろな情報を発信しています.
中高数学に関しては自然を再現しよう役に立つ中高数学 中高数学お散歩コース
大学数学に関しては現代数学観光ツアーなどの無料の通信講座があります.
その他にも無料の通信講座はこちらのページにまとまっています.
ご興味のある方はぜひお気軽にご登録ください!

  • このエントリーをはてなブックマークに追加
  • LINEで送る

関連記事

  • コメント (2)

  • トラックバックは利用できません。

  1. [] の型がわからないのでそこから b の型を推論できないからですね。 たとえば ([]::(Fractional a) => [(String, a)]) というふうに型情報を書いておけばいけます。 明示しないとき assoc が返す値の型は Maybe b ということまでしかわかりませんから、 b の型が特定できません。 入力が [] のときに返ってくるのは Nothing ですから b の型は関係なさそうな気もしますが、たとえば Maybe IntNothingMaybe CharNothing は (型がことなるので) 比較したりできません。

    assoc の型の方でもう少し b の型を制限する、たとえば (Num b) という制限をいれても大丈夫です。

      • phasetr
      • 2017年 1月23日

      いつもコメントありがとうございます。
      今立て込んでいてコードを確認する時間が取れないので、
      時間が取れ次第コードを直して確認します。

このサイトについて

数学・物理の情報を中心にアカデミックな話題を発信しています。詳しいプロフィールはこちらから。通信講座を中心に数学や物理を独学しやすい環境づくりを目指して日々活動しています。
  • このエントリーをはてなブックマークに追加
  • LINEで送る

YouTube チャンネル登録

講義など動画を使った形式の方が良いコンテンツは動画にしています。ぜひチャンネル登録を!

メルマガ登録

メルマガ登録ページからご登録ください。 数学・物理の専門的な情報と大学受験向けのメルマガの 2 種類があります。

役に立つ・面白い記事があればクリックを!

記事の編集ページから「おすすめ記事」を複数選択してください。