Elm基礎文法やってみた

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

[きっとこれから流行る関数型言語Elmを使えばHTML/CSS/JavaScriptを統一できるよ❗ - Qiita](https://qiita.com/imtaplet/items/71003c4e2fa322f4298f)


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

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

```elm
max (abs -150) (abs 100)
```
とすることでabs関数を利用し個々の数字のマイナスを外し、max関数で比較した。

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

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

## if文
条件分岐はif式を使用する。
![then.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/611952/5373ff4b-5a50-76a2-339e-c33b3bba9e59.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`はいらない。
条件分岐のときの`True`や`False`はあくまで説明のために書いてるだけで実際はほとんど使わない。
なぜこの間違いをしてしまったかというと、参考書に

```elm
if True then "Hello" else "Bye"
```
書籍「[基礎からわかる Elm](https://www.amazon.co.jp/dp/B07P253FPG/)」P.41より引用。

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


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

```elm
> List.length [1,2,3] -- 長さを取得する
3
```
といった結果が出る。
当然リストのリスト（入れ子構造）も出来る。この場合一番上の入れ子だけ表示される。

```elm
> List.length [[[]]]
1
```
またlistにはmapという概念があり、
List.map {関数} [数字,数字,数字]
![1216px-CPT_Haskell_Map_function.svg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/611952/cb4ab3fb-9195-6217-cb8d-65c646f49761.png)
引用: https://commons.wikimedia.org/wiki/File:CPT_Haskell_Map_function.svg
これは関数型言語の特徴である！

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


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

```elm
> (0,"a")
(0,"a") : ( number, String )
```
というようにリストと違って、異なる型（数字や文字列）を混合していれることができる。
ただしリストと違ってすべての要素に関数を適用することが出来ない。

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

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

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

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

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

```

### カスタム型とcase-of 式

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

#### カスタム型

```elm
type Gender = Male | Female | XXX
```
のようなtype {任意の型名} でを記入してどんなバリアント（種類）があるかを定義できる。

##### case-of 式

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

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

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

```elm
type Gender = Male | Female | XXX

getMyGender = Male

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

main = text (genderToString getMyGender)
```


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