Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ghciでの定数と関数の型の変化 #10

Open
maeken2010 opened this issue Dec 28, 2014 · 3 comments
Open

ghciでの定数と関数の型の変化 #10

maeken2010 opened this issue Dec 28, 2014 · 3 comments
Labels

Comments

@maeken2010
Copy link

除算の小数部分を求めたくて以下の関数syoussと定数n,mを用意したのですが,

syouss n m = (n/m) - (fromIntegral (n`div`m))
n = 10
m = 3

ghciで:loadで読み込んで実行しようとするとエラーに

ghci> syouss n m
<interactive>:3:1:
    No instance for (Fractional Integer) arising from a use of ‘syouss’
    In the expression: syouss n m
    In an equation for ‘it’: it = syouss n m

nとmの型を調べるとなぜかIntegerでした.
ghciでlet a = 10のようにすると型はa :: Num a => aとなりましたがsyoussはまだ実行できませんでした.

ghci> let a = 10
ghci> let b = 3
ghci> :t a
a :: Num a => a
ghci> syouss a b

<interactive>:8:1:
    No instance for (Show a0) arising from a use of ‘print’
    The type variable ‘a0’ is ambiguous
    Note: there are several potential instances:
      instance Show Double -- Defined in ‘GHC.Float’
      instance Show Float -- Defined in ‘GHC.Float’
      instance (Integral a, Show a) => Show (GHC.Real.Ratio a)
        -- Defined in ‘GHC.Real’
      ...plus 44 others
    In a stmt of an interactive GHCi command: print it

試しにghciで(a/b) - (fromIntegral (adivb))を直接実行すると計算できました.

ghci> (a/b) - (fromIntegral (a`div`b))
0.3333333333333335

型を見てみましたがなぜか異なっていました

ghci> :t (a/b) - (fromIntegral (a`div`b))
(a/b) - (fromIntegral (a`div`b)) :: Fractional a => a
ghci> :t syouss
syouss :: (Integral a, Fractional a) => a -> a -> a

長くなってしまいまいましたが,以上より2つの疑問点があります.

  1. 定数の型がファイルからの:loadとghciでのletで何故型が違うのか
  2. 数式(a/b) - (fromIntegral (adivb))を関数定義した時と直接実行した時に何故型が変わるのか
@maeken2010
Copy link
Author

書きながら思ったのですが除算の小数部分自体はRatio用いる方法がありますね.このままでは整数値同士しかできませんが…

import Data.Ratio
syous n m = fromRational $ (n`mod`m) % m 

@atton atton added the Haskell label Dec 30, 2014
@atton
Copy link
Member

atton commented Dec 30, 2014

まず2 から答えます。

  1. 数式(a/b) - (fromIntegral (adivb))を関数定義した時と直接実行した時に何故型が変わるのか

についてですけれど、 ghci で定義している文だと関数じゃなくて定数だからです。

syouss は関数なので、

  • ghci> (a/b) - (fromIntegral (adivb))

ではなくて

  • ghci> \a b -> (a/b) - (fromIntegral (adivb))

です。

そうすると

Prelude> :t \a b -> (a/b) - (fromIntegral (a`div`b))
\a b -> (a/b) - (fromIntegral (a`div`b))
  :: (Integral a, Fractional a) => a -> a -> a

*Main> :t syouss 
syouss :: (Integral a, Fractional a) => a -> a -> a

と同じです。

そして、 Int の値が実行できない問題はこっちでも発生します。

*Main> (\a b -> (a/b) - (fromIntegral (a`div`b))) (10 :: Int) (3 :: Int)

<interactive>:17:12:
    No instance for (Fractional Int) arising from a use of ‘/’
    In the first argument of ‘(-)’, namely ‘(a / b)’
    In the expression: (a / b) - (fromIntegral (a `div` b))
    In the expression: \ a b -> (a / b) - (fromIntegral (a `div` b))

これはどうしてかと言えば Int だと Fractional に明示的に変換しないといけないからです。

Num, Fractional, Integral の関係は
https://www.haskell.org/onlinereport/basic.html
とかになってます。

Integral である Integer にすると、 Fractional の型クラスを持ってないからエラーになるわけです。

@atton
Copy link
Member

atton commented Dec 30, 2014

ん? ごめんちょっと問題を勘違いしてたかも。 上の全然関係無いこと言ってる説が。ちょっと待って

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants