0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Elm基礎文法やってみた

Last updated at Posted at 2020-09-02

Elmというプログラミング言語を下記記事を見て面白そうだったのでやってみた!

きっとこれから流行る関数型言語Elmを使えばHTML/CSS/JavaScriptを統一できるよ❗ - Qiita

ローカルでElmのウェブアプリケーションを作る

まずは練習としてBMIを計算するアプリケーションを作ろうと思ったが。。。

そのためには基礎文法を学ぶ必要があった。
なので基礎文法から学習することに。

関数の適用方法

複数の関数を呼び出す方法

100の絶対値と-150の絶対値のどちらか大きい数字をかえす
前提としてabsとmax関数を使用するものとする。
abs関数は絶対値を表示する関数。
max関数は大きい数字を表示する関数。

という問題があった場合、

回答例1.elm
abs 100 -150

という風に解こうとしたため、

The `abs` function expects 1 argument, but it got 2 instead.

というコンパイルエラーがでた。
これは頭の中でabs関数がそれぞれの数字に適用されてくれると思ってしまったからである。
これは関数には型があって、どんな型の引数を何個渡せるかは決められていてそうでない場合はコンパイルエラーが出る仕様だからである。

今回は絶対値を出したいだけなので、式の中でマイナスを外して、2つ以上の引数を比較できるmax関数で比較すれば良い。

max (abs -150) (abs 100)

とすることでabs関数を利用し個々の数字のマイナスを外し、max関数で比較した。

関数の適用

例えば、「与えられた数字が負であるかどうかを判定する」場合の関数を定義したい場合は?
ここでの関数名はisNegativeとする。

isNegative n = n < 0

と定義する。
TIPS:isやhasなどが先頭に来る関数はほぼBool(TrueやFalse)という文化がある。そうじゃないものはわりと叩かれ気味なので気をつける。

if文

条件分岐はif式を使用する。
then.PNG
引用: https://office-hack.com/excel/if-vba/

if True then "Hello" else "Bye" と書くとHelloが表示される。
では先程書いた isNegative を条件式に適用させたい場合は?

if (isNegative 100) True then "Hello" else "Bye" と書いてしまったが、
if (isNegative 100) then "Hello" else "Bye"と書いてTrueはいらない。
条件分岐のときのTrueFalseはあくまで説明のために書いてるだけで実際はほとんど使わない。
なぜこの間違いをしてしまったかというと、参考書に

if True then "Hello" else "Bye"

書籍「基礎からわかる Elm」P.41より引用。

とシンタックスハイライトなしで記入されていたため、 True もif式に必要なキーワードだと思ってしまった。

リスト

[1,2,3]
["hello","world"]
などといったリストが作れる。

> List.length [1,2,3] -- 長さを取得する
3

といった結果が出る。
当然リストのリスト(入れ子構造)も出来る。この場合一番上の入れ子だけ表示される。

> List.length [[[]]]
1

またlistにはmapという概念があり、
List.map {関数} [数字,数字,数字]
1216px-CPT_Haskell_Map_function.svg.png
引用: https://commons.wikimedia.org/wiki/File:CPT_Haskell_Map_function.svg
これは関数型言語の特徴である!

List.map isNegative [1, -1, 2]

タプル

タプルとはリストと違い異なる型を入れることが出来る。

> (0,"a")
(0,"a") : ( number, String )

というようにリストと違って、異なる型(数字や文字列)を混合していれることができる。
ただしリストと違ってすべての要素に関数を適用することが出来ない。

タプルの主な用途として、複数の値を返したい場合に使用する。

レコード

タプルはそれぞれの要素に名前はついていないが、レコードはそれぞれの要素に名前をつけることができる。
要素に名前をつけたものをプロパティという。

> { id = 1 , name = "Alice" , age = 30}
{ age = 30, id = 1, name = "Alice" }
    : { age : number, id : number1, name : String }

Type alias

Type aliasとは型の別名。
既存の型に別名を与えられる。
型定義自体が長くなってしまう場合、一つの名前を与えたほうがわかりやすい。

type alias User =
    { id : Int
    , name : String
    , image : String
    }

カスタム型とcase-of 式

カスタム型といって全く新しい型を作ることが出来る。
type Gender = Male | Female | XXX
のようにMaleとFemaleとXXXのいずれかを値にとる型を作成できる。

カスタム型

type Gender = Male | Female | XXX

のようなtype {任意の型名} でを記入してどんなバリアント(種類)があるかを定義できる。

case-of 式
case {任意の式} of
    {パターンマッチ} -> {結果の式} 

が入る(インデントはスペース4個)
JavaScriptなどは、if文でtrueかfalseしか条件分岐できないが、case-of式はパターンマッチという強力な機構によってあらゆる型の条件を指定できる。また抜けている条件分岐があったらコンパイルエラーをだしてくれる。

実際にカスタム型を定義して、それを使う関数を書いてみる。
性別のカスタム型を定義して、その値を文字列に変換するコードを例題にする。

type Gender = Male | Female | XXX

getMyGender = Male

genderToString : Gender -> String
genderToString gender = 
    case gender of 
        Male -> "男"
        Female -> "女"
        XXX -> "どちらでもない"

main = text (genderToString getMyGender)

感想

Elm言語はほかのオブジェクト指向言語と比べ自分にあっているように感じた。
引き続き勉強していきたい!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?