[前][次][番号順一覧][スレッド一覧]

haskell-jp:517

From: Yusaku Hashimoto <nonowarn@g...>
Date: Sun, 31 Jan 2010 19:07:25 +0900
Subject: Re: [haskell-jp:516] Re: Real Wold Haskell 3章の練習問題

こんにちは。

> Prelude> 10 / 4
> 2.5
>
> と実行すると,分母,分子とも整数でも計算できることが分かりました

このときの 10 や 4 の型は Double です。
また、このとき (/) :: Double -> Double -> Double なので 10 / 4 :: Double です。

ちょっと説明しますね。

10 / 4 がエラーにならないのも、10 や 4 の型を追ってみるとわかります。

    $ ghci -ignore-dot-ghci
    Prelude> :t 10
    10 :: (Num t) => t
    Prelude> :t 4
    4 :: (Num t) => t

(Num t) => t というのは、Num クラスのインスタンスの型のどれかの型、という意味です。

また、(/) :: (Fractional t) => t -> t -> t です。
Fractional は分数を表すクラスです。Num をスーパークラスに持ちます。

    Prelude> :i Fractional
    class (Num a) => Fractional a where
      (/) :: a -> a -> a
      (... 略 ...)

したがって、10 / 4 :: (Fractional t) => t になるのですが、
この値の実際の型ってこれだけじゃわかりませんよね。
Fractional のインスタンスには Double とか Float などがあるんですが、
実際の型はどれやねん、というのを教えてやらなくてはいけません。
Haskell は静的型付けを持つ言語だからです。

だけど、インタプリタを電卓代わりに使うとき、
いちいち型を指定するのは邪魔臭いです。
そこで、Defaulting という仕組みがあります。
ある型クラスに対して、デフォルトの型を決めてとりあえずそれでやりましょう、
という仕組みです。

たとえば、(Num a) => a という型の値は、この Defaulting で Integer になります。
おなじように、(Fractional t) => t という型の値は、Defaulting で Double になります。

というわけで、インタプリタから 10 / 4 と叩くと、
10 や 4 は Double に Defaulting され、(/) :: Double -> Double -> Double が決まり、
2.5 が Double として出てきます。

また、Defaulting はある意味で静的型付けのうまみを捨ててしまいます。
なので、Defaulting を警告するオプションがコンパイラについています。

    $ ghci -ignore-dot-ghci -fwarn-type-defaults
    Prelude> 10 / 4

    <interactive>:1:0:
        Warning: Defaulting the following constraint(s) to type `Double'
                 `Fractional t' arising from a use of `/' at <interactive>:1:0-5
        In the expression: 10 / 4
        In the definition of `it': it = 10 / 4

    <interactive>:1:0:
        Warning: Defaulting the following constraint(s) to type `Double'
                 `Fractional t' arising from a use of `/' at <interactive>:1:0-5
        In the expression: 10 / 4
        In the definition of `it': it = 10 / 4
    2.5

ご参考になりましたら幸いです。

--nwn
http://flavors.me/nwn

2010/1/31 Maehara Masahide <maehrm@g...>:
> 前原と申します。
>
> On Sun, 31 Jan 2010 09:52:12 +0900,
> Nonaka Akira <nonaka@m...> wrote:
>
>> あいかわらずReal Wold Haskellを少しずつ読んでいます.3章の練習問題
>> (P72)をやってみました.宜しければ識者の方の添削をお願いします.
>
> 添削ではなくて便乗質問です。。。すみません。
>
> 練習問題3を解くときに疑問に思ったことがありました。練習問題3は,「リス
> トの平均値を計算する関数を書きなさい。」という問題です。fromIntegral関
> 数を使って…というヒントがあったので,以下のように作成してみました。
>
> Prelude> let average xs = sum xs / fromIntegral (length xs)
> Prelude> average [1,2,3,4]
> 2.5
>
> 正常に動作しているようですので,ここで終われば良かったのですが,
>
> Prelude> 10 / 4
> 2.5
>
> と実行すると,分母,分子とも整数でも計算できることが分かりましたので,
> fromIntegralを除いて定義しても良いのでは思いました。しかし,以下のよう
> にエラーが出力されます。
>
> Prelude> let average xs = sum xs / (length xs)
>
> <interactive>:1:17:
>  No instance for (Fractional Int)
>   arising from a use of `/' at <interactive>:1:17-36
>  Possible fix: add an instance declaration for (Fractional Int)
>  In the expression: sum xs / (length xs)
>  In the definition of `average': average xs = sum xs / (length xs)
>
> Haskellは,型をしっかり扱わなければならないので,上記のエラーが出たの
> は納得出来るのですが,そうであれば,10 / 4 もエラーが出てくれると,す
> べて納得出来るのにと思ってしまいます。
> この件は,
>    http://d.hatena.ne.jp/rahaema/20100114
> に書き,もう忘れかけていたのですが,野中さんのメールを見て,便乗させて
> いただきました。アドバイスがいただければ幸いです。
>
> では。
> --
> 宮崎県立都城工業高等学校(情報制御システム科)
> 前原 正英 <maehrm@g...>
>

[前][次][番号順一覧][スレッド一覧]

       515 2010-01-31 09:52 [nonaka@m...         ] Real Wold Haskell 3章の練習問題        
       516 2010-01-31 17:09 ┣[maehrm@g...         ]                                       
->     517 2010-01-31 19:07 ┃┗[nonowarn@g...       ] Re: [haskell-jp:516] Re: Real Wold Haskell 3章の練習問題
       520 2010-01-31 20:56 ┃ ┗[maehrm@g...         ] Re:  Real Wold Haskell 3章の練習問題
       521 2010-01-31 22:11 ┃  ┗[nonowarn@g...       ] Re: [haskell-jp:520] Re: Real Wold Haskell 3章の練習問題
       518 2010-01-31 19:24 ┣[nonowarn@g...       ] Re: [haskell-jp:515] Real Wold Haskell 3章の練習問題
   @   519 2010-01-31 19:35 ┃┗[nonaka@m...         ]                                     
       522 2010-02-01 09:16 ┗[ikegami.da@g...     ] Re: [haskell-jp:515] Real Wold Haskell 3章の練習問題
       523 2010-02-01 09:34  ┗[ikegami.da@g...     ]                                     
       524 2010-02-01 10:40   ┗[ikegami.da@g...     ]                                   
       525 2010-02-01 22:04    ┗[masahiro.sakai@g... ] Re: Real Wold Haskell 3章の練習問題
       526 2010-02-03 12:53     ┗[ikegami.da@g...     ] Re: [haskell-jp:525] Re: Real Wold Haskell 3章の練習問題