Elmのデータ型定義

Tech > Elm

type

typeで型を定義する、直積データ、直和データの書き方で、基本的にパターンマッチで値を取得する

type Msg
    = Get (Result Http.Error CRes)
    | Send
    | Up Cate
    | Down Cate
    | HResp (Result Error CRes)

type alias

Haskellのレコード構文的な書き方、型のインスタンスと関数で値を取得できるようになる

type alias Cate
    = { unCateId : Int
      , unCatePid : Maybe Int
      , unCateName : String
      , unCateVer : Int
      , unCatePos : Int
      } 

こうすることで

...
   [ a [ href ("/catelist/" ++ (String.fromInt c.unCateId))
...

ドット「.」を利用して値にアクセスが可能になる、余談ですがHaskellですと

unCateId cate

のように基本的に逆になるので、75%の確率で間違います、でもElmの書き方の方がいいですね。

再帰的データ宣言

少し注意が必要なのは、再帰的に宣言する場合に

type alias Cate
    = { unCateId : Int
      , unCatePid : Maybe Int
      , unCateName : String
      , unCateVer : Int
      , unCatePos : Int
      , unCateList : List Cate
      }

type aliasで宣言した場合、 List Cate のように自分自身を再帰的に定義すると

~/Code/Houbou $ make cate
cd jssrc/category && echo "javascript build..." && npm run build
javascript build...

> hb_category@1.0.0 build /home/cuomo/Code/Houbou/jssrc/category
> elm make src/Category.elm --output=../../static/js/hb_category.js

Detected problems in 1 module.
-- ALIAS PROBLEM ---------------------------------------------- src/Category.elm

This type alias is recursive, forming an infinite type!

33| type alias Cate
               ^^^^
When I expand a recursive type alias, it just keeps getting bigger and bigger.
So dealiasing results in an infinitely large type! Try this instead:

    type Cate =
        Cate
            { unCateId : Int
            , unCatePid : Maybe Int
            , unCateName : String
            , unCateVer : Int
            , unCatePos : Int
            , unCateList : List Cate
            }

Hint: This is kind of a subtle distinction. I suggested the naive fix, but I
recommend reading <https://elm-lang.org/0.19.1/recursive-alias> for ideas on how
to do better.

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! hb_category@1.0.0 build: `elm make src/Category.elm --output=../../static/js/hb_category.js`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the hb_category@1.0.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/cuomo/.npm/_logs/2021-08-27T11_44_42_019Z-debug.log
make: *** [Makefile:18: cate] エラー 1

「無限の型定義になるのでダメよ」 と叱られます、このバージョンは0.19.1ですので将来のバージョンで改善されるかもしれませんが、現状では無理です。 そこで、少し工作をし、別の型でくるみます。

type NestCate = NestCate Cate

type alias Cate
    = { unCateId : Int
      , unCatePid : Maybe Int
      , unCateName : String
      , unCateVer : Int
      , unCatePos : Int
      , unCateList : List NestCate
      }

こうすることで、コンパイラを納得させることが可能です。

再帰的データのデコード方法

このデータ型のjson情報を、decodeする場合は

import Json.Decode as D
...
...
inCateDecoder : D.Decoder Cate
inCateDecoder =
    D.map6 Cate
        (D.field "unCateId" D.int)
        (D.field "unCatePid" (D.nullable D.int))
        (D.field "unCateName" D.string)
        (D.field "unCateVer" D.int)
        (D.field "unCatePos" D.int)
        (D.field "unCateList" (D.list inNestCateDecoder))

inNestCateDecoder : D.Decoder NestCate
inNestCateDecoder =
    D.map NestCate (D.lazy (\_ -> inCateDecoder))

inNestCateDecoder で NestCate をデコードさせるように見せかけて、また inCateDecoder をループ的に呼び出すという、なんとも頭がスパゲッティになりそうな書き方になります。

Posted on 2021-08-27 20:58:49

はじめまして

お茶の国静岡で、焼酎のお茶割なんか罰当たりで飲んだことはありません、常に一番搾りを嗜む静岡極東のBBQerです、最近まわりのエンジニアの方々がお料理を上手にやっている姿を恨めしそうに横目に見ながら、軟骨ピリ辛チクワを食べています、みなさんよろしく。

Posted

Amazon

tags

家系 日本酒池 広井酒店 やがら やっぱた 刺身 丸干し 鯵 東京マラソン fpm php82 servant thread spawn Rust Oracle Linux 8 microcode firmware linux openzfs zfs gitea 麒麟 真野鶴 金鶴 日本酒 docker oracle pod podman cli virtualbox VirtualBox epub mobi calibre mask lens ワンライナー php 海 redmine Linux Oracle Map OMap omap map 夏 BBQ カテゴリ管理 カテゴリ timestamp date oracle database string 麦焼酎 ダービー process 磨き蒸留 広井酒店、日本酒 芋焼酎 酒 焼酎 ゆるキャン 広井酒店、日本酒池 spring framework java persistent spring session session spring hdbc-odbc persistent-odbc odbc day utctime スィート レマンの森 elm初期化 elm バイク xlr80 esqueleto database xl2tpd strongswan vpn l2tp ipsec 正月 ゲーム grub nginx systemctl portage 豚骨 圧力鍋 yesod-auth-hashdb yesod-auth