Haskellをラクガク

2006-09-18久々のHaskell

第6章 基本的な値 - 数値 00:43

ここからは難しくなりそうなので、細かいところを確かめつつやっていこうかと。まずは数値について。

IntとIntegerが違うってホント?

a = (16::Integer)
b = (3::Int)
c = a+b
main = print c
IntOrInteger.hs:3:6:
    Couldn't match `Integer' against `Int'
      Expected type: Integer
      Inferred type: Int
    In the second argument of `(+)', namely `b'
    In the definition of `c': c = a + b

あら、ホントだ。どうにかしてくれても良さそうなもんだけど、Haskellの型はかなり厳密なものらしい。

でも、

a = (16::Integer)
main = print (a+3)
19

これはOK。つまり、数値リテラル文脈によって変換されるけど、一旦型を決めてしまうとIntとIntegerですら互換性がないみたい。

リテラルだけど型を付けてやると、

a = (16::Integer)
main = print (a+(3::Int))
IntOrInteger.hs:2:17:
    Couldn't match `Integer' against `Int'
      Expected type: Integer
      Inferred type: Int
    In the expression: 3 :: Int
    In the second argument of `(+)', namely `(3 :: Int)'

怒られる。

基本的な値 - 文字列 01:07

文字といったらChar。文字列といったら[Char]。[Char]の別名はString。これは結構分かりやすい。JavaみたいにStringだけやけに特別だったりしないところが良い。

a = "hogehoge"
b = "foobar"::String
c = ['f','o','o','b','a','r']::[Char]
main = do   print $ "hogehoge" == a
            print $ b == c
True
True

Haskellの「==」は同値かどうかを判定するものなので、イマイチ面白みに欠ける…。のでIntとIntegerだったらどうかというと、

a = 3::Integer
b = 4::Int
main = print $ a==b
IntEqInteger.hs:3:18:
    Couldn't match `Integer' against `Int'
      Expected type: Integer
      Inferred type: Int
    In the second argument of `(==)', namely `b'
    In the second argument of `($)', namely `a == b'

怒られる。

基本的な値 - タプル 01:27

複数の値を纏めて扱うタプル。タプルいいよな。でもタプルが組み込まれている言語ってPythonくらいしか知らないけど。

ということで、同値性チェック。

a = (3::Int,"hoge")
b = (3, "hoge")
c = (3::Integer, "hoge")

main = do   print $ a == b
            print $ b == c
            print $ c == a
TeqT.hs:6:25:
    Couldn't match `Int' against `Integer'
      Expected type: (Int, [Char])
      Inferred type: (Integer, [Char])
    In the second argument of `(==)', namely `c'
    In the second argument of `($)', namely `b == c'

あれ?「b == c」でダメか。「c == a」でダメって怒られると予想したんだけど…。タプルに数値リテラル適用すると、Intになっちゃうってことかな。それとも、先に「a == b」の評価をしたが故にfst bがIntと思われちゃったのかな。

ということで、「a == b」と「b == c」の実行順序を入れ替えてみる。

a = (3::Int,"hoge")
b = (3, "hoge")
c = (3::Integer, "hoge")

main = do   print $ b == c
            print $ a == b
            print $ c == a
TeqT.hs:6:25:
    Couldn't match `Int' against `Integer'
      Expected type: (Int, [Char])
      Inferred type: (Integer, [Char])
    In the second argument of `(==)', namely `b'
    In the second argument of `($)', namely `a == b'

やっぱり「a == b」で型が違うと怒られる。だから、bの型はIntegerなんだろう。数値リテラルみたいに文脈で型が決まるものは、そうは言えども一度決まっちゃったらずっとその型として扱われるのか。面白いー。

AntioneAntione 2007/07/02 05:07 http://64fdebd2c057be50b9c19d9a1e08d879-t.xxpogy.org <a href="http://64fdebd2c057be50b9c19d9a1e08d879-h.xxpogy.org">64fdebd2c057be50b9c19d9a1e08d879</a> [url]http://64fdebd2c057be50b9c19d9a1e08d879-b1.xxpogy.org[/url] [url=http://64fdebd2c057be50b9c19d9a1e08d879-b2.xxpogy.org]64fdebd2c057be50b9c19d9a1e08d879[/url] [u]http://64fdebd2c057be50b9c19d9a1e08d879-b3.xxpogy.org[/u] 9dc75301cfe28cfb0fb3d1863c1dee5e

ゲスト



トラックバック - http://haskell.g.hatena.ne.jp/hsyd/20060918