ホームに戻る
 Haskellのサンプル

-- コメント

{- 複数行コメント -}

{-
"abc"
333
2.0
-1
-1
0
1
-2
256
4
3
2
-1
2
6
97
'b'
abcdef
ghijkl
ans:123
False
1
1
'b'
[(1,'a'),(2,'b')]
([1,2],"cd")
True
[0,1,2,3,4,5]
[1,2,3,4,5,6,7,8,9,10]
[1,2]
4
0
[1,2,3,4,5,6]
[2,3,5]
[1,2,3]
["a","b","c"]
"d\ne\nf\n"
"ghi"
[7,5,3,1]
["a","b","c"]
"d e"
[1,1]
True
False
False
False
"Yes"
"Yes"
False
[3,4,11]
6
3
4
42
">a1"
">a1:a2"
">>b1"
">>>b1"
"Just_Mona 3"
-}

import Data.Char                -- Data.Char をインポート

type Cs = String                -- 型に別名をつける
newtype IntArray = Ia [Int]     -- 新しい型を定義
data Color = RC | GC | BC       -- 列挙型的
data Number = S String | I Int  -- 共用体的
data Dat = D{s::String, i::Int} -- 構造体的

dat1 :: Dat                     -- Dat 型の dat1 を定義
dat1 = D "abc" 333              -- "abc" 333 をセット

main = do print (s dat1)        -- "abc"を表示
          print $ i dat1        -- 333 を表示 $ は () と同じ
          print $ 2.0 / 1.0     -- Float か Double のみ
          print $ (-1)          -- - は関数なので () で囲う
          print $ (-2) `div` 3  -- 割り算 負の方向へまるめる
          print $ (-2) `quot` 3 -- 割り算 0の方向へまるめる
          print $ (-2) `mod` 3  -- div のあまり
          print $ (-2) `rem` 3  -- quot のあまり
          print $ 2 ^ 8         -- 累乗
          print $ abs (-4)      -- 絶対値
          print $ ceiling 2.1   -- 2.1 を下回らない整数
          print $ floor 2.1     -- 2.1 を超えない整数
          print $ truncate (-1.1) -- 0 と -1.1 の間で -1.1 に近い整数
          print $ round 1.5     -- 1.5 に最も近い整数 2つの場合は偶数
          print (addOne 5)      -- 関数 addOne を呼ぶ
          print $ ord 'a'       -- 文字を数字 97 に
          print $ chr 98        -- 数字を文字 'b' に
          putStr "abc"          -- 文字列の表示
          putStrLn "def"        -- 改行つき文字列の表示
          putStrLn $ "ghi" ++ "jkl" -- ++ で要素の結合
          putStrLn $ "ans:" ++ show 123 -- show で数字を文字列に
          print $ not True      -- not で Bool 型を反転
          print $ if (2 == (addOne 1)) then 1 else 0 -- if式(if文ではないことに注意)
          print $ fst (1, 'a')  -- 最初の要素を得る
          print $ snd (2, 'b')  -- 2番目の要素を得る
          print $ zip [1..2] ['a'..'b'] -- unzip の逆
          print $ unzip [(1,'c'),(2,'d')] -- zip の逆
          print $ null []       -- 空リストであれば True を返す
          print $ 0 : [1..5]    -- 0 から 5 のリスト
          print $ [1..2]++[3..10] -- 1 から 10 のリスト
          print $ [x | x <- [1.. 5], x < 3] -- 1 から 2 のリスト
          print $ length ['a'..'d'] -- リストの要素数を返す
          print $ head [0..6]   -- 先頭の 0 を返す
          print $ tail [0..6]   -- [1..5] を返す
          print $ map addOne [1, 2, 4] -- map でリストのすべての要素に addOne を適用
          print $ take 3 [1..5] -- take 最初の3要素をリストで得る
          print $ lines "a\nb\nc\n" -- 改行で分離
          print $ unlines ["d","e","f"] -- 改行をはさんで結合
          print $ concat ["g","h","i"] -- 文字列へ結合
          print $ reverse [1,3..8] -- リストを反転
          print $ words "a b c" -- 空行で分離
          print $ unwords ["d", "e"] -- words の逆
          print $ filter isOne [1, 2, 3, 1] -- 条件を満たす要素をリストで返す
          print $ any odd [1, 5, 3, 1] -- すべての要素が条件を満たせば True を返す
          print $ isOne 2       -- 関数の例1
          print $ isTwo 3       -- 関数の例2
          print $ isThree 4     -- 関数の例3
          print $ myIf True "Yes" "No" -- 自作の if
          print $ (myIf True "Yes") "No" -- 引数は必ずしも1度に与えなくとも良い
          print $ isOneElement [3, 5] -- 関数の例4
          print $ addListOne [2,3,10] -- 関数の例5
          print $ f1 1 -- 関数の例6
          print $ f2 2 -- 関数の例7
          print $ (\x -> x + 1) 3 -- 無名関数
          print $ (f1 . f2) 4 -- 合成関数 f2 して f1 する
          class_test            -- 型クラス
          monad_test            -- モナド

{- 1を足す関数 -}
addOne :: Int -> Integer -- Integer型は 32 bitとかの制限が無い
addOne x = toInteger (x + 1) -- toInteger の逆は fromInteger

{- 1 であれば True を返す -}
isOne :: Int -> Bool
isOne x = if (x == 1) then True else False

{- 2 であれば True を返す -}
isTwo :: Int -> Bool
isTwo x
  | (x == 2) = True
  | otherwise = False

{- 3 であれば True を返す -}
isThree :: Int -> Bool
isThree x = case x of 
              3 -> True
              _ -> False

{- 自作の if -}
myIf :: Bool -> a -> a -> a
myIf True t f = t
myIf False t f = f

{- リストの要素が1つなら True を返す -}
isOneElement :: [a] -> Bool
isOneElement [_] = True
isOneElement _ = False

{- すべての要素に1を足す -}
addListOne :: [Int] -> [Int]
addListOne [] = []
addListOne all@(x:xs) = x + 1 : addListOne xs -- all はすべて x は head、xs は tail となる

{- 部分的に使用できる変数 n1, n2 を定義する例 -}
f1 x = let n1 = x + 1
           n2 = x + 2
        in n1 * n2

{- 部分的に使用できる関数 addOne を定義する例 -}
f2 x = addOne x
  where
    addOne n = n + 1

{- 型 Type の定義 -}
data Type = A | B

{- 型クラス Eq のインスタンスを定義 -}
instance Eq Type where
  (==) A A = True
  (==) A B = False
  (==) B A = False
  (==) B B = True

{- 型クラス Eq のインスタンスを自動生成 -}
data Sample = Sample String deriving Eq

{- 型クラス ClassA を定義 -}
class ClassA a where
  fa :: a -> String
  fa _ = "Error"

{- ClassA を継承した型クラス ClassB を定義 -}
class (ClassA a) => ClassB a where
  fb :: a -> String

{- データ型の定義 -}
data A1 = A1 String
data A2 = A2 String String
data B1 = B1 String

{- 型クラスのインスタンスの定義 -}
instance ClassA A1 where
  fa(A1 s) = ">" ++ s

instance ClassA A2 where
  fa(A2 s1 s2) = ">" ++ s1 ++ ":" ++ s2

{- ClassB は ClassA を継承しているので
   ClassB の定義を書く場合には
   かならず ClassA に対するインスタンスを用意する。-}
instance ClassA B1 where
  fa(B1 s) = ">>" ++ s

instance ClassB B1 where
  fb(B1 s) = ">>>" ++ s

{- データ型に値をセット -}
a1 = A1 "a1"
a2 = A2 "a1" "a2"
b1 = B1 "b1"

{- 型クラスを使用した例 -}
class_test = do print $ fa a1
                print $ fa a2
                print $ fa b1
                print $ fb b1

{- モナドで使用するデータ型を定義 -}
data Mona a = Not_Mona | Just_Mona a deriving (Show,Eq)

{- モナドで使用する関数を定義 -}
check :: (Eq a) => a -> a -> Mona a
check x y = if (x == y) then (Just_Mona x) else Not_Mona

{- モナドクラス >>= と return の挙動を定義 -}
instance Monad Mona where
  Not_Mona  >>= f = Not_Mona
  (Just_Mona x) >>= f = f x
  return x        = Just_Mona x

{- モナドを使用した例 -}
monad_test = do print $ show ((return 3 >>= check 3) >>= check 3)

inserted by FC2 system