Haskell に慣れるため、Koltin と比較しながら、身近な題材を使ってあれこれやってみます。
名前+OS+価格の一覧であるコンピュータリストがあったとして、これを操作してみます。
computer.hs:
type Name = String
type Price = Int
data OS = MacOS | IOS | ChromeOS | Windows deriving (Show, Eq)
data Computer = Computer { name :: Name
, os :: OS
, price :: Price } deriving Show
computerList :: [Computer]
computerList = [ Computer "macbook air" MacOS 98000
, Computer "macbook pro" MacOS 248000
, Computer "iPad pro" IOS 128000
, Computer "iPad air" IOS 68000
, Computer "pixelbook" ChromeOS 158000
, Computer "pixelbook Go" ChromeOS 78000
, Computer "surface laptop" Windows 168000
, Computer "surface laptop Go" Windows 68000
, Computer "surface pro" Windows 198000
, Computer "surface Go" Windows 48000
, Computer "thinkpad x1" Windows 178000
]
GHCi を起動して コンピュータリストを表示し、take, drop, reverse, filter してみます。
$ ghci
> :load computer.hs
> computerList
[Computer {name = "macbook air", os = MacOS, price = 98000},Computer {name = "macbook pro", os = MacOS, price = 248000},Computer {name = "iPad pro", os = IOS, price = 128000},Computer {name = "iPad air", os = IOS, price = 68000},Computer {name = "pixelbook", os = Windows, price = 158000},Computer {name = "pixelbook Go", os = Windows, price = 78000},Computer {name = "surface laptop", os = Windows, price = 168000},Computer {name = "surface laptop Go", os = Windows, price = 68000},Computer {name = "surface pro", os = Windows, price = 198000},Computer {name = "surface Go", os = Windows, price = 48000},Computer {name = "thinkpad x1", os = Windows, price = 178000}]
先頭の2件だけ take します:
> take 2 computerList
[Computer {name = "macbook air", os = MacOS, price = 98000},Computer {name = "macbook pro", os = MacOS, price = 248000}]
末尾の2件だけ取得します。 そのためには computerList の件数を数えて、-2 した値を使って drop:
> length computerList
> drop (11-2) computerList
[Computer {name = "surface Go", os = Windows, price = 48000},Computer {name = "thinkpad x1", os = Windows, price = 178000}]
または、リストをリバースしてから take 2 してもよい:
> take 2 $ reverse computerList
[Computer {name = "thinkpad x1", os = Windows, price = 178000},Computer {name = "surface Go", os = Windows, price = 48000}]
次に 先頭のコンピュータを取り出しOSを確認:
> head computerList
Computer {name = "macbook air", os = MacOS, price = 98000}
> os $ head computerList
MacOS
OS が iOS のコンピュータだけを取り出す:
> filter (\c -> (os c) == IOS) computerList
[Computer {name = "iPad pro", os = IOS, price = 128000},Computer {name = "iPad air", os = IOS, price = 68000}]
うまく、iOS のコンピュータだけ抽出できています。
この内容を Kotlin スクリプトに置きかえて確認してみます。
computer.main.kts:
enum class OS {
MacOS, IOS, ChromeOS, Windows
}
class Computer(val name: String, val os: OS, val price: Int){
override fun toString(): String {
return "<$name $os $price>"
}
}
val computerList = listOf(
Computer("macbook air", OS.MacOS, 98000),
Computer("macbook pro", OS.MacOS, 248000),
Computer("iPad pro", OS.IOS, 128000),
Computer("iPad air", OS.IOS, 68000),
Computer("pixelbook", OS.ChromeOS, 158000),
Computer("pixelbook Go", OS.ChromeOS, 78000),
Computer("surface laptop", OS.Windows, 168000),
Computer("surface laptop Go", OS.Windows, 68000),
Computer("surface pro", OS.Windows, 198000),
Computer("surface Go", OS.Windows, 48000),
Computer("thinkpad x1", OS.Windows, 178000) )
println( computerList )
kotlin コマンドで実行します:
$ kotlin computer.main.kts
[<macbook air MacOS 98000>, <macbook pro MacOS 248000>, <iPad pro IOS 128000>, <iPad air IOS 68000>, <pixelbook ChromeOS 158000>, <pixelbook Go ChromeOS 78000>, <surface laptop Windows 168000>, <surface laptop Go Windows 68000>, <surface pro Windows 198000>, <surface Go Windows 48000>, <thinkpad x1 Windows 178000>]
うまくいきました。
それでは続いて、take, drop, reverse, filter するコードを computer.main.kts に追加。
println( "take 2 computerList" )
println( computerList.take(2) )
println( "drop (11-2) computerList" )
println( computerList.drop( computerList.size -2 ) )
println( "take 2 $ reverse computerList")
println( computerList.asReversed().take(2) )
println( "filter (\\c -> (os c) == IOS) computerList" )
println( computerList.filter( {c -> c.os == OS.IOS} ) )
Kotlin ではリストの内容を反転させるときに reverse() ではなく、asReverse() を使うことで意図通りの処理ができました。
実行してみます。
$ kotlin computer.main.kts
take 2 computerList
[<macbook air MacOS 98000>, <macbook pro MacOS 248000>]
drop (11-2) computerList
[<surface Go Windows 48000>, <thinkpad x1 Windows 178000>]
take 2 $ reverse computerList
[<thinkpad x1 Windows 178000>, <surface Go Windows 48000>]
filter (\c -> (os c) == IOS) computerList
[<iPad pro IOS 128000>, <iPad air IOS 68000>]
うまくいきました。
ほとんど Haskell と同じ感覚で Kotlin に翻訳できました。