ことり、穂乃果と一緒に学ぶHaskell(入門)その1「代数的データ型の定義」

Posted on 2017/05/06
Tags: ラブライブ!で学ぶ, ことり、穂乃果と一緒に学ぶHaskell, Haskell

前置き(海未ちゃん)

海未「この度は『ことり、穂乃果と一緒に学ぶHaskell(入門)』にお越しいただき、ありがとうございます」
海未「本企画はこちらの偉大なブログ様に触発されたものです。 是非こちらもご覧ください」

海未「キャラ崩壊を含む可能性があります。 ご容赦くださいますよう」
海未「それでは、よろしくお願いします 」



ことり、穂乃果と一緒に学ぶHaskell(入門)その1「代数的データ型の定義」

ーー ライブ練習終わり着替え後(部室) ーー

ことり「ふう〜、練習つかれたぁ」
ことり「ん……?」

ドタドタドタ

穂乃果「ことりちゃん〜〜、たすけてー!!」
ことり「わっ、ホノカチャン!! ど、どうしたの〜〜?」
穂乃果「この前、選択授業を選んだじゃん? 私はHaskellを選んで、1回目の授業を受けたんだけど、全然わからなくって……」



穂乃果「前にJavaは習ったんだけど、HaskellってJavaとは全然違うみたいで、頭が追いつかなくて」
ことり「音ノ木坂は、必修の授業でJavaをやるもんね! うーん」

穂乃果「ことりちゃんって、たしかHaskell……やってたよね! だから教えて欲しくって。 ダメ……?」ウルウル

ことり(ううっ、穂乃果ちゃんにそんな顔されたら……ことりだって断れないよぅ)

ことり「わ、わかったよ! 大丈夫だよ、わたしにまかせて☆」
穂乃果「わぁ、ありがとうことりちゃん〜!」

ことり「穂乃果ちゃん、PCって今、持ってる?」
穂乃果「もちろん! 音ノ木坂の生徒はみんな学校から、ノートPCを貸し受けてるからね! よいしょっと」

ことり「うんうん。 じゃあちょっと見せてね。 ……よし、OSはArchLinux。 stackとテキストエディタは入ってるみたいだね」



ことり「じゃあ、やっていこうか☆」
穂乃果「よーし、私! ファイトだよっ!」

代数的データ型の定義

穂乃果「この前は『代数的データ型』っていうのについて習ったんだけど……今日はここを教えて欲しいなあ」
ことり「代数的データ型はHaskellの最もたる優れた要素だね!」

ことり「じゃあ、まずは代数的データ型の定義方法について説明するね」
ことり「穂乃果ちゃん、Javaでclassってあったよね。 こんな感じのclassをJavaで書いてみてくれる?」

  1. クラス名: Member
  2. コンストラクタで以下の値を受け取る
    1. String name
    2. int age
  3. その値を、コンストラクタで以下のpublicプロパティに代入する
    1. name > this.name
    2. age > this.age

穂乃果「はーい! これくらい簡単だよ!」

class Member {
	public String name;
	public int age;
	public Member(String name, int age) {
		this.name = name;
		this.age = age;
	}
}

ことり「よくできました☆」ナデナデ
穂乃果「わーい! わーい!」エヘヘヘヘ

ことり「このコードをHaskellに直していくね」
ことり「Haskellでは、代数的データ型をdataというキーワードを使って、作っていきます」

data Member = Member String Int

穂乃果「すごーい! 1行で書けちゃうんだー!」
ことり「うん、Haskellはよく、記述量が少ないって言われるんだー。 って穂乃果ちゃん、これくらいは授業でも見たはずじゃ……」
穂乃果「えへへ、実はdataがこういうのを作るものだってことも、まだわかってなくて……」

穂乃果「あれ、でもnameとか、ageっていう名前は書かないでいいの?」
ことり「うん、Haskellではプロパティ名みたいなものが必要ないことが多くって、そういう場合はつけないかなぁ」
ことり「名前をつけることもできるんだけど、今はまだ置いておいてね」
穂乃果「はい。 ことり先生!」
ことり「ことり先生なんて……エヘヘ」

ことり「これを実際に使うには……そうだ穂乃果ちゃん。 mainってもう習ったかなあ?」
穂乃果「習った! 穂乃果、mainならわかるよ!」

main :: IO ()
main = do
  print 10

穂乃果「こういうやつ!」
ことり「さすが穂乃果ちゃん♪」
穂乃果「あっでもね……:: IO ()とか、doとかもよくわかってなくって……」
ことり「大丈夫だよ、そこらへんもおいおいやっていくからね!」
穂乃果「お願いしますことり先生ー!!」ドゲザー

ことり「じゃあこれDataType.hsっていうファイル名で保存して、実行……っと」

$ stack runghc -- DataType.hs
10

穂乃果「10が表示されたね! これくらいなら穂乃果もわかるよっ!」
ことり「さすがさすが♪」

ことり「じゃあちょっと前の内容に戻って……Javaで、Memberクラスのインスタンスを生成するコードを書いてみてくれるかな」

public class Test {
	public static void main(String[] args) {
		Member kotori = new Member("南ことり", 16);
	}
}

穂乃果「こんな感じ?」
ことり「そんな感じだね、ありがとう♪ これをHaskellに直すとこうなるよ」

main :: IO ()
main = do
  let kotori = Member "kotori" 16
  return ()

穂乃果「let? return ()?」
ことり「letは変数の定義に使うキーワードだよ! Haskellだと、変数名の前に型名を書かなくてもいいの!」
ことり「return ()は……今は単なるno operationだと思っておいて欲しいな☆」
穂乃果「no operationは、何もしない命令だったよね。 わかりましたっ!」

穂乃果「ってあれ、“kotori”? “南ことり”じゃだめなの?」
ことり「うっ、穂乃果ちゃんするどいね……実はHaskell、そのままじゃ日本語を扱うときに色々と不安定なんだ。  表示できたりできなかったり……シンプルに表示するくらいはできるんだけど ……Stringで直接マルチバイト文字列を使わない方がいいんだ」

ことり「ある型を使えば問題ないんだけど、今回の内容とは外れちゃうから、これも今は無視してくれる……かな」
穂乃果「ある型? はーい」

ことり(今回はごく基本に絞ってるから無視してほしいものが多くって、困っちゃうなー……)ウー

型クラスの自動導出

ことり「次は、Memberデータ型をmainで表示してみるよ」

ことり「Javaでは、toString()っていうメソッドをオーバーライドすることがあったよね」
穂乃果「クラスインスタンスをprintするときに、いい感じにするあれ……だよね?」

class Member {
	public String name;
	public int age;
	public Member(String name, int age) {
		this.name = name;
		this.age = age;
	}

	@Override
	public String toString() {
		return "Member " + this.name + " " + this.age;
	}
}

ことり「そうそう! これはこう書けるよ」

data Member = Member String Int
  deriving (Show)

ことり「deriving (Show)って行を追加したよ」
穂乃果「これも1行で書けちゃうの!?」
ことり「うん、そうなんだ♪ でも、もっと表示結果をカスタマイズしたいときは、もうちょっと書く必要があるかな」
ことり「こういう単純なパターンを実装したい時には、derivingっていうのを使うよ!

main :: IO ()
main = do
  let kotori = Member "kotori" 16
  print kotori

ことり「実行っと」

$ stack runghc -- DataType.hs
Member "kotori" 16

穂乃果「すごーい! ちゃんと表示されたー!」
ことり「やったね!」

穂乃果「でもことりちゃん、このShowってなに?」
ことり「それはね穂乃果ちゃん、いわゆる型クラスって言って……」

…………

(次回に続く)

参考にしたページ


 疑問点があれば、Twitterでリプライくれれば(そのリプライを見逃してなければ)返すよ!
@public_ai000ya - Twitter



この記事はこちらから修正リクエストを送ることができます。
ことり、穂乃果と一緒に学ぶHaskell(入門)その1「代数的データ型の定義」 - github
ゴミ箱ボタンの左にある、鉛筆ボタンを押してね!