LoginSignup
11
0

More than 5 years have passed since last update.

(ネストした)recordの更新でエラーが出る

Last updated at Posted at 2016-12-20

こんなエラーが出るんです。

I ran into something unexpected when parsing your code! - I am looking for one of the following things:

"'"
"|"
an equals sign '='
more letters in this name
whitespace

もしくはこれ

I ran into something unexpected when parsing your code! - I am looking for one of the following things:

a closing bracket '}'
a lower case name
whitespace

この記事の内容

recordを更新していて上記のようなエラーが出た理由

エラーになるコード

ネストしたレコードや他モジュールからrecordとってきて更新しようとしたときにエラーになります

type alias Point =
  { x : Int
  , y : Int
  }


type alias Model =
  { point : Point
  , something : String
  }


moveX : Int -> Model -> Model
moveX dx model =
  { model | point = { model.point | x = model.point.x + dx }}

これはネストしている場合です。PointとPointが入ったModelを作って、moveXでPointのxを変更しているコードです
特に問題ないように見えますが、このコードはコンパイルが通りません

model.pointの位置に一番上のエラーが出ます。コンパイルエラーなんですけど、最初なんでそうなるのかわかりませんでした。合法に見えるでんすよね

理由

recordのupdate構文には制限が掛かっていて、{|の間には値(?)しか置けません
正確な用語はわからないんですけど1トークンしか置けない感じです

{ model | -- Ok

{ modelPoint | -- Ok

{ model.point | -- 関数適用はだめ

{ toRecord 1 "something" | -- 関数適用はだめ

{ AModule.record | -- 修飾名もだめ

Elm Discussを読んでみたんですが、
- あいまいさが残る
- { model.point |の返却値はmodelとも読めるし(中のpointだけ更新する構文にも見える)、pointとも読める
- パースがちょっと大変
- 制限なくすとちょっと便利になるけど、言語の方向としてそっちが正しいか確信を持てないので変えません
- プロジェクトでやっぱりないとつらいってなったら報告してね

みたいな感じで、8日目のjinjorさんの記事で触れられている通りの雰囲気です

解決方法

上で言及したdiscussや関連するissueなどを読んでいただくのがいいと思うんですけど、いくつか解決策をあげておきます

moveX : Int -> Model -> Model
moveX dx model =
  let
    point = model.point
  in
    { model | point = { point | x = model.point.x + dx }}

letで定義し直してしまう方法です。
簡単に置き換えるだけですが、ちょっとダサい気もしますね

moveX : Int -> Model -> Model
moveX dx model =
  { model | point = updatePoint model.point }

別の関数をかまします。そもそもネストしたものをその場で一気に変更するのは見づらいしやめようって感じです

あとは使い方わかっていないんですが、Lensってライブラリを使ってみるとか

追記
elm-monocleを使ってみた方がいるのでそちらをご参照ください

終わり

終わり。Elm Advent Calendar、今年は盛りだくさんなのでElm始めるにはいいタイミングかもしれませんね。
土曜も担当します

11
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
11
0