Skip to content

Instantly share code, notes, and snippets.

@phasetr phasetr/error.hs
Last active Sep 7, 2016

Embed
What would you like to do?
assoc :: 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
-- 目的:受け取った ekimei0 までの距離を lst から探して返す
-- 見つからなかったら例外 Not_found を起こす
assoc :: String -> [(String, Double)] -> Maybe Double
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
(* 目的:受け取った ekimei0 までの距離を lst から探して返す *)
(* 見つからなかったら例外 Not_found を起こす *)
(* assoc : 'a -> ('a * 'b) list -> 'b *)
let rec assoc ekimei0 lst = match lst with
[] -> raise Not_found
| (ekimei, kyori) :: rest ->
if ekimei = ekimei0 then kyori else assoc ekimei0 rest
(* 'b についても多相の型となる。*)
(* テスト *)
(* let test1 = assoc "後楽園" [] *)
(* Not_found を起こす *)
let test2 = assoc "後楽園" [("新大塚", 1.2); ("後楽園", 1.8)] = 1.8
(* let test3 = assoc "池袋" [("新大塚", 1.2); ("後楽園", 1.8)] *)
(* Not_found を起こす *)
@phasetr

This comment has been minimized.

Copy link
Owner Author

commented Sep 7, 2016

ex18_3.ml が大元で、それを error.hs のように書き換えたら上記コメントのようなエラーが出た。

多相関数を定義するのに任意の a では駄目で == を使っているから
Eq のインスタンス(?)でないと駄目ということだと理解した。

それはそれとして ex18_3.hs のように具体的に String とかにしておけばいいというのもわかった。

OCaml コードのように a とか b のまま押し切るために Haskell ではどう書けばいいのだろうというアレ。

error.hs は次のエラー表示が出る。

2016-09-07-225035.tmp.hs:4:6: error:
    • No instance for (Eq a) arising from a use of ‘==’
      Possible fix:
        add (Eq a) to the context of
          the type signature for:
            assoc :: a -> [(a, b)] -> Maybe b
    • In the expression: fst x == ekimei0
      In the expression:
        if fst x == ekimei0 then Just (snd x) else assoc ekimei0 xs
      In an equation for ‘assoc’:
          assoc ekimei0 (x : xs)
            = if fst x == ekimei0 then Just (snd x) else assoc ekimei0 xs

2016-09-07-225035.tmp.hs:8: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 }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.