Elmのmoduleのimportが知りたくて――。
北海道札幌市内の住宅で、Elmのmoduleのimport処理を、とりあえず雑にqualified importしたとして、札幌中央警察署は22日、北海道札幌市、無職すがわに容疑者(24)をmodule適当にimportした容疑で逮捕したと発表した。
「Html.Attributes.maxが使いたかった」と容疑を認めているという。
今回のお話
モジュール内の名前がかぶった場合
Basics.maxとHtml.Attributes.max
progress
のmax
属性が怒られてしまった
import Html exposing (..) import Html.Attributes exposing (max, value) , progress [ Html.Attributes.max "100" , Html.Attributes.value "80" ] []
これをどうするか
教えてもらった
importのやつは、asキーワードが使えます。https://t.co/XikKCdcbXO
— ABAB↑↓BA (@ababupdownba) 2020年8月21日
Attribute とするか 必要な関数だけexposeすることが多いですね(.. 使うのはhtmlくらい? いやケースバイケースでサボるか) pic.twitter.com/7VbkUVTKh2
↑ありがとうございます!
— 🐊すがわに🐊 (@nek0roll) 2020年8月22日
Htmlは(..)で、それ以外は必要な関数(Attributeとかはid, name, valueぐらいだと思うので)をインポートする感じかなと思ってました
リンク読んでみます!
id,name
との衝突を考えてないポンコツid, name, value なかなか被りそうな名前なので、asした方が良さそうかもですね(と言っても決まりはないので個人の好みです)
— ABAB↑↓BA (@ababupdownba) 2020年8月22日
確かにでした…
— 🐊すがわに🐊 (@nek0roll) 2020年8月22日
import Html.Attributes as Attribute
が個人的に結構好きなので、これで進めてみようと思います!
ABAB↑↓BAさんが自分の発言を拾ってくれて本当にありがたいです
モチベがお餅モチモチ雪見だいふくです
参考ページを読み解く
qualified import
module名.関数名
で呼び出す事ができる
import Html.Attributes
完全修飾名指定で使える
import Html.Attributes , progress [ Html.Attributes.max "100" , Html.Attributes.value "80" ] []
import Html.Attributes as Attribute
別名を指定して関数を使える
import Html.Attributes as Attribute , progress [ Attribute.max "100" , Attribute.value "80" ] []
open import
関数名
で直接呼び出すことができる(module
名が不要)
import Html.Attributes exposing (..)
module
内の関数を全部まとめて使える
※以下ケースだとmax
がBasics.max
と衝突するのでNG
import Html.Attributes exposing (..) , progress [ Html.Attributes.max "100" , Html.Attributes.value "80" ] []
import Html.Attributes exposing (max, value)
指定したmodule
内の関数が使える
※以下ケースだとmax
がBasics.max
と衝突するのでNG
import Html.Attributes exposing (max, value) , progress [ Html.Attributes.max "100" , Html.Attributes.value "80" ] []
asとexposing両方
import Html.Attributes as Attribute exposing (..)
import Html.Attributes as Attribute exposing (..) , progress [ Attributes.max "100" , value "80" ] []
感想
import Html.Attributes
文字数が少ないぐらいしかいいところが思いつかない
毎回Html.Attributes
って書きたくない- import
Html.Attributes as Attribute
明示的でCOOL。結構好き
後述するexposing
との合わせ技がかなり好み import Html.Attributes exposing (..)
雑だけど楽
衝突しやすい関数名とか地獄見そう(map
とか)import Html.Attributes exposing (max, value)
サンプルでも使われてるし、何import
してるのか明示的で好き
ただ衝突が悲しいimport Html.Attributes as Attribute exposing (..)
雑に楽したい俺の心を満たす素敵なヤツ
衝突しないやつは(..)
で問題なく使える
衝突したらAttributes.
で使える
おまけ
compiler/imports.md at 9d97114702bf6846cab622a2203f60c2d4ebedf2 · elm/compiler · GitHub
elm/compiler
にインポートのヒントがあったので読んでみた
雑意訳
英検三級レベルなので温かい目でみてください
import
import モジュール名
でモジュールをインポートして使用できます
Html
モジュールのdiv
関数を使う場合は以下の記法です
import Html main = Html.div [] []
Html
モジュールのHtml
型を使う場合は以下の記法です
import Html main : Html.Html msg main = Html.div [] []
※注意
モジュールは他のモジュールを含まないので
import Html
だけではHtml.Attributes
を使用することはできません
たまたまHtml
が重なっているだけの別のモジュールです
使用したい場合はimport Html.Attribtues
でインポートする必要があります
as
qualified import
するのがベストプラクティスですが、名前が長くなることがあります
その場合はas
で別名をつけることができます
import Html import Html.Attributes as A main = Html.div [ A.style "color" "red" ] [ Html.text "Hello!" ]
これでHtml.Attributes
モジュールの関数や型をA
で呼び出すことができます
exposing
下書き等でサクッと使いたい場合exposing
を使用できます
import Html exposing (..) import Html.Attributes exposing (style) main : Html msg main = div [ style "color" "red" ] [ text "Hello!" ]
exposing (..)
はモジュール名無しで関数や型を呼び出すことができます
上の例では
Html
モジュールのHtml
型Html
モジュールのdiv
,text
関数Html.Attributes
のstyle
関数
がモジュール名無しで呼び出されています
※注意
一見スッキリしているように見えますが、たくさんのモジュールをexposing (..)
した場合、
きっとすぐにコード内の関数がどこから呼ばれているのか混乱するでしょう
そしてimport
を整理し始めるはずです
ポイントは(..)
を使用しないことです!
as and exposing
as
とexposing
を使用して、バランス良くインポートできます
import Html exposing (Html, div, text) import Html.Attributes as A exposing (style) main : Html msg main = div [ A.class "greeting", style "color" "red" ] [ text "Hello!" ]
Html.Attributes.style
exposing (style)
でインポートしているのでstyle
(モジュール名なし)Html.Attributes.class
Html.Attributes as A
でインポートしているのでA.class
(as
で指定したモジュール名)
となっています
デフォルトでインポートされるモジュールについて
一般的によく使用されるモジュールの中には、
Elm
コンパイラが自動的に全てのファイルにインポートを追加するものがあります
デフォルトでインポートされるモジュールは以下のようなものがあります
import Basics exposing (..) import List exposing (List, (::)) import Maybe exposing (Maybe(..)) import Result exposing (Result(..)) import String import Tuple import Debug import Platform exposing (Program) import Platform.Cmd as Cmd exposing (Cmd) import Platform.Sub as Sub exposing (Sub)
上記のインポートは、モジュールの先頭に常にあると考えられられます
(すがわに:暗黙的なインポートが常に存在する感じ)
Maybe
型はElm
のエラー処理を行うための基本的なものであり、基本的な言語の一部であるという主張もあります
また、Elm
を使い慣れてくると、「毎回Maybe
モジュールをインポートするのが面倒だ」という意見もあります
いずれにしても、デフォルトのインポートはそういった意味では理想的ではないということはわかっているので、デフォルトのインポートは最小限に留めています
※注意
とても大きな(何百もの関数を持つ)モジュールをインポートしても、
Elm
コンパイラは自動的にデッドコードを検出し、モジュール内の未使用の関数はアセットに含めないため、アセットのサイズを心配する必要はありません
まとめ&感想
- 基本的にはqualified importが良さそう
exposing (..)
は学習段階ではいいけど、実際にアプリケーションを実装する場合は避けるべき
Html.Attributes
とかはHtml.Attributes as A
とか短くするのが良さそう
今のうちに癖つけておこうかなBasics.max
とHtml.Attributes.max
が被る理由がわかった
「Basics
なんてインポートしてないな…暗黙的なやつかな…」とふわふわしてた部分がハッキリした- 事情とかベストプラクティス書いてくれるのめちゃくちゃ親切
開発元が決めてくれたらそれに沿って進められるし、ありがたい
追記
exposingを使うのはほんのちょっとだけにしておくのをお勧めします。
まったく使わないか、ひとつのインポートだけで使うのが理想的でしょう。
そうしないと、読むときに型や関数がどのモジュールから来ているのかを把握するのが難しくなっていくことがあります。
「待って、filterPostByはどこから来たんだっけ? 引数は何を取るんだっけ?」
exposingを追加するにつれて、コードを読んでいくのはどんどん難しくなっていきます。
私はimport Html exposing (..) をよく使いますが、それ以外ではまったく使いません。
まずは基本的なimportを使い、もし特に長いモジュール名であるときはasを使うことをお勧めします!
改めてガイド読んだら全部書いてましt(ここで日記は途切れている)