2006-07-17
■ パターンマッチ
フツケル 168頁
id :: a -> a id x = x 仮引数の「x」が変数パターンです。 変数パターンはどんな値に対してもマッチし、その値に変数を束縛します。
--変数パターンのサンプルコード hoge x = print x main = do hoge 1 hoge 10
最初引用した変数パターンの説明に出てくる、「その値に変数を束縛します」を以下のように勘違いしていました。
hoge xの変数xを値に束縛するということは、hoge 10はhoge xにマッチするから、xを10に束縛する。Haskellは再代入は出来ない。
従ってhogeメソッドを抜けてもxの値は10であるはず(?)ということで以下のようなコードを書いていました。結果は「Not in scope: `x'」とエラーが表示されて実行出来ません。
xは仮引数ですから、メソッドを抜けたら値を消失するからエラーが出て当たり前と言えば当たり前なのですが、束縛しますと書いてあったのでメソッドを抜けても10にxが束縛されているのかと思ってしまいました(^_^;)
hoge x = x main = do print $ hoge 1 print x
2006-07-16
■ 昇順ソートと降順ソート
import List list = [2,9,8,49,299,34,99,103,3] main = do putStr "Orginal " print list putStr "ASC " print $ sortBy(\x y -> compare x y )list -- 昇順ソート putStr "DESC " print $ sortBy(\x y -> compare y x )list -- 降順ソート
- 実行結果
D:\Development\PracticeHaskell\work20060715>runghc sample05.hs Orginal [2,9,8,49,299,34,99,103,3] ASC [2,3,8,9,34,49,99,103,299] DESC [299,103,99,49,34,9,8,3,2]
■ 6文字以上の文字列はどれとどれ?
リストの中に入っている文字列で、文字列の長さが6文字以上のものをリストに入れて返してもらう処理を書いてみました。
- パターン1
import List list = ["Oasis","THE CRANBERRIES","Keane","Maroon 5","DEF LEPPARD"] main = print $ filter isGreaterThan6Characters list isGreaterThan6Characters x = (length x) >= 6
import List list = ["Oasis","THE CRANBERRIES","Keane","Maroon 5","DEF LEPPARD"] main = print $ filter (\x -> (length x) >= 6) list
import List list = ["Oasis","THE CRANBERRIES","Keane","Maroon 5","DEF LEPPARD"] main = print $ filter ( ( >=6 ) . length) list
- パターン1から3の実行結果
["THE CRANBERRIES","Maroon 5","DEF LEPPARD"]
2006-07-10
「フツケル」131頁から134の学習
■ 整数型
- Int型とInteger型
Haskellの整数型にはInt型とInteger型の二種類ある。
- 数値リテラルの型
文脈によって同じ5でもInt型にもなるし、Integer型にもなる。また浮動小数点型にもなる。文脈が数値リテラルの型を決める。
- 数値リテラルの型を限定
文脈によらず数値リテラルの型を限定するには以下のように宣言する。
- x = (2 :: Int)
この場合は数値リテラルの2がInt型と宣言され、Int型の2を変数xに束縛しています。
- y = (3 :: Integer)
この場合は数値リテラルの3はInteger型と宣言され、Integer型の3を変数yに束縛しています。
- 型の異なる同士の演算
型が異なる同士の演算を行うには、明示的に型を変換する必要がある。
-- xの型はInt型 x = (15 :: Int) -- yの型はInteger型 y = (10 :: Integer) -- xとyの型は異なるので、このままだと演算は出来ない。 -- x又はyのどちらかを一方の型に変換することによって演算が可能になる。 main = do print $ (toInteger x) + y -- xの型をInteger型に変換 print $ x + (fromInteger y) -- yの型をInt型に変換 print $ (fromIntegral x) + y -- xの型をInteger型に変換 print $ x + (fromIntegral y) -- yの型をInt型に変換
- toInteger x、fromInteger x及びfromIntegral xの定義
- toInteger x
Int型の値xをInteger型に変換します。
- fromInteger x
Integer型の値xを数値型に変換します。但し返り値の型は文脈で決まります。
整数型ではなく数値型に変換するという点に注目。演算相手がFloat型だとfromInteger xはFloat型を返すということかな?(未確認)
- fromIntegral x
Int型又はInteger型の値xを数値型に変換します。但し返り値の型は文脈で決まります。この関数もfromInteger同様に整数型ではなく数値型に変換するという点に注目。自分の演算相手がDouble型であれば、Double型に変換して返してくれるということかな?(未確認)
2006-07-06
■ 真偽値
「フツケル」129頁から130頁のまとめ
- (&&)関数
- (&&) Bool -> Bool -> Bool
- x && yはxとyがともにTrueのときTrueを返します。それ以外のときはFalseを返します。
- (||)関数
- (||) :: Bool -> Bool -> Bool
- x || yはxとyのいずれかがTrueのときTrueを返します。
- サンプルプログラム
-- ファイル名:sample_bool.hs main = do print $ ("not (1 == 1)",not (1 == 1)) print $ ("not (1 == 3)",not (1 == 3)) print $ ("(10 == 10) && (20 == 20)",(10 == 10) && (20 == 20)) print $ ("(62 == 30) && (20 == 20)",(62 == 30) && (20 == 20)) print $ ("(30 == 30) && (20 == 10)",(30 == 30) && (20 == 10)) print $ ("(5 == 2 ) && (3 == 1)",(5 == 2 ) && (3 == 1)) print $ ("('a' == 'a') || ('b' == 'b')",('a' == 'a') || ('b' == 'b')) print $ ("('a' == 'a') || ('b' == 'c')",('a' == 'a') || ('b' == 'c')) print $ ("('a' == 'd') || ('b' == 'b')",('a' == 'd') || ('b' == 'b')) print $ ("('p' == 'q') || ('r' == 's')",('p' == 'q') || ('r' == 's'))
- サンプルプログラムの実行結果
d:\Development\PracticeHaskell>runghc sample_bool.hs ("not (1 == 1)",False) ("not (1 == 3)",True) ("(10 == 10) && (20 == 20)",True) ("(62 == 30) && (20 == 20)",False) ("(30 == 30) && (20 == 10)",False) ("(5 == 2 ) && (3 == 1)",False) ("('a' == 'a') || ('b' == 'b')",True) ("('a' == 'a') || ('b' == 'c')",True) ("('a' == 'd') || ('b' == 'b')",True) ("('p' == 'q') || ('r' == 's')",False)
2006-07-05モジュール
「フツケル」の250頁
- Greetingモジュール
--ファイル名:greeting.hs module Greeting where hello = putStr "Hello,World!"
--ファイル名:greeting_client.hs import Greeting main = hello
- greeting_client.hsを実行してみました。
D:\Development\PracticeHaskell\work20060704>runghc greeting_client.hs Hello,World!
D:\Development\PracticeHaskell\work20060704>ghc greeting.hs -o greeting C:/ghc/ghc-6.4.2/libHSrts.a(Main.o)(.text+0x1d):Main.c: undefined reference to ` __stginit_ZCMain' C:/ghc/ghc-6.4.2/libHSrts.a(Main.o)(.text+0x43):Main.c: undefined reference to ` ZCMain_main_closure' collect2: ld returned 1 exit status
--Greetingモジュールの中身そのままで、ファイル名をgreeting_mod.hsに変更 module Greeting where hello = putStr "Hello,World!"
--greeting_client.hsの実行結果 D:\Development\PracticeHaskell\work20060704>runghc greeting_client.hs Could not find module `Greeting': use -v to see a list of the files searched for (imported from greeting_client.hs)
Greetingモジュールをロードするために、Greetingというファイルを探したけど見つからなかったということですね。モジュール名とファイル名は一致していないといけないのかも
--ファイル名:greeting.hs module GreetingMod where hello = putStr "Hello,World!"
--greeting_client.hsを実行した結果 D:\Development\PracticeHaskell\work20060704>runghc greeting_client.hs ./Greeting.hs: file name does not match module name `GreetingMod'
ファイル名がモジュール名と一致していないと分かりやすいエラーが表示されました。やはりファイル名とモジュール名は一致していないといけないということでしょうか(^_^;)
無限リストでもOK