Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Haskell と Elm と JSON の話

416 vues

Publié le

NGK2017B の発表資料
会場にて急ピッチで作ったので間違ってるかも....

Publié dans : Technologie
  • Soyez le premier à commenter

Haskell と Elm と JSON の話

  1. 1. Haskell と Elm と JSON の話 ひげ
  2. 2. $ whoami 名古屋の学生 好きなジャンル: 言語処理系 好きな言語: Haskell でアルバイトしてる 流石関数型の街名古屋(?)、探したらあった 春から東京...
  3. 3. 本題
  4. 4. Elm は JSON つらい? Elmには組込みでJSONに関するパッケージがある JSON を任意の型に変換する 他言語で良くあるハッシュマップではなく 変換の関数を 自分で書かなくてはいけない 組込み型の変換関数はある パーサーコンビネーターみたいに書く(?) たぶんこれがつらいんだと思う
  5. 5. 例 type alias Guid = String type alias Player = { name: String , active: Bool , id: Guid } player : Decoder Player player = succeed Player |: ("name" := string) |: ("active" := bool) |: ("id" := string)
  6. 6. めんどいなら Haskell
  7. 7. Haskell の JSON HaskellもJSONを任意の型に変換する aeson パッケージ 型クラスを使ってデコーダー/エンコーダーを定義 する 結局手作業か??
  8. 8. Generics があります! (正確には Haskell でなくて GHC だけど)
  9. 9. Haskell の Generics Haskell の型の構造を型として扱う(??) 型クラスのインスタンスを勝手に作ってくれる 雑に言えば インスタンスを定義する側は楽 型クラスを定義する側が大変
  10. 10. 例 {-# LANGUAGE DeriveGeneric #-} type Guid = String data Player = { name : String , active : Bool , id : Guid } deriving (Generics, Show) instance FromJSON Player instance ToJSON Player
  11. 11. Elm を捨てて Haskell を使え
  12. 12. ではない!
  13. 13. 使うのは elm-export
  14. 14. Haskellの型 -> Elmの型 をしてくれるパッケージ
  15. 15. ついでに JSONデコーダーも生成してくれる
  16. 16. 例 こういう型から data Comment = Comment { postId :: Int , text :: Text , mainCategories :: (String, String) , published :: Bool , created :: UTCTime } deriving (Generic, ElmType)
  17. 17. 例 type alias Comment = { postId : Int , text : String , mainCategories : (String, String) , published : Bool , created : Date } decodeComment : Decoder Comment decodeComment = decode Comment |> required "postId" int |> required "text" string |> required "mainCategories" (map2 (,) (index 0 string) (index 1 string)) |> required "published" bool |> required "created" decodeDate
  18. 18. 問題がある
  19. 19. Haskellのレコード型はクソ ホントはこんなコード書いたらHaskell共和国から追 放される {-# LANGUAGE DeriveGeneric #-} type Guid = String data Player = { name : String , active : Bool , id : Guid } deriving (Generics, Show)
  20. 20. Haskellのレコード型はクソ ホントはこんなコード書いたらHaskell共和国から追 放される {-# LANGUAGE DeriveGeneric #-} type Guid = String data Player = { name : String , active : Bool , id : Guid -- これこれ } deriving (Generics, Show) Elm は .id という関数が生成されるので平気(たぶん)
  21. 21. そこで拡張可能レコード
  22. 22. 例 extensible というヤバいパッケージを使う type Player = Record '[ "name" >: String , "active" >: Bool , "id" >: Guide ] player :: Player player = #name @= "hige" <: #active @= True <: #id @= "123" <: emptyRecord player ^. #name 参照には lens というヤバいパッケージを使う
  23. 23. 拡張可能レコードの JSON は?? これです instance Forall (KeyValue KnownSymbol FromJSON) xs => FromJSON (Record xs) where parseJSON = withObject "Object" $ v -> hgenerateFor (Proxy :: Proxy (KeyValue KnownSymbol FromJSON)) $ m -> let k = symbolVal (proxyAssocKey m) in case HM.lookup (fromString k) v of Just a -> Field . return <$> parseJSON a Nothing -> fail $ "Missing key: " `mappend` k (雑に言えば) 拡張可能レコードという一つの型として扱う
  24. 24. まとめ Elm で JSON はつらい? つ elm-format with Haskell Elm のレコード型を Haskell で書けない? つ 拡張可能レコード 実際に ElmとHaskellでサンプル書いた記事 がある ので詳しくはコレを見て(?) Haskell 最高じゃん
  25. 25. おしまい

×