SlideShare a Scribd company logo
GitHub での Haskell の色が
変わったので
ひげ
$ whoami
好きな言語: Haskell, Ruby
Haskell でバイトしてる
言語系が一番好き
最近は Elixir × Elm はじめました
本題
FastHub という GitHub Client を
愛用してる
しかし....
色が....
緑....!!! (だった)
室は最近 Haskell の色が変わった
github/linguist の PR#3728 で確認できる
なので PR を出そう
せっかくなので他に無いかを
調べよう!
Haskell で !!
(※ Haskell である必要はありません)
どう管理してるか
GitHub は YAML ,FastHub は JSON で管理してる
なので
ざっくりと考えると
1. ファイルをそれぞれ読み込んで
2. YAML と JSON の型にデコードし
3. 色だけを比較して
4. 違うモノだけ出力
(最終的なコードはコチラ)
使うパッケージ
aeson と yaml
JSON/YAML のデコード/エンコードパッケージ
yaml のベースは aeson
bytestring と text
Haskell の文字列型 その2とその3
unordered-containers
連想配列パッケージ
他にもあると思うけど aeson が使ってるから
使うパッケージ
extensible と lens
今回の目玉パッケージ (ただし lens はオマケ)
Haskell のレコードを扱いやすくしてくれる
(他にも機能はあるんだけど、詳しくは割愛)
-- 普通のレコード
data User = User { id :: Int, name :: String }
-- extensible
type User = Record '[ "id" :> Int, "name" :> String ]
定義は大して変わらないけど...
なぜ標準のレコードが扱いにくいかはココを参照
型
type GitHubLanguage =
Record '[
"type" :> Maybe Text, "aliases" :> Maybe [Text],
"ace_mode" :> Maybe Text, "codemirror_mode" :> Maybe Text,
"wrap" :> Maybe Bool, "extensions" :> Maybe [Text],
"interpreters" :> Maybe [Text], "searchable" :> Maybe Bool,
"language_id" :> Int, "color" :> Maybe Text,
"tm_scope" :> Maybe Text, "group" :> Maybe Text
]
type GitHubLanguages = HashMap Text GitHubLanguage
type FastHubLanguage =
Record '[
"color" :> Maybe Text,
"url" :> Text
]
type FastHubLanguages = HashMap Text FastHubLanguage
型クラス
type C = KeyValue KnownSymbol FromJSON'
instance Forall C xs => FromJSON (Record xs) where
parseJSON = withObject "Object" $
v -> hgenerateFor (Proxy :: Proxy C) $
m -> let k = symbolVal (proxyAssocKey m) in
case HM.lookup (fromString k) v of
Just a -> Field . return <$> parseJSON a
Nothing ->
maybe (fail $ "Missing key: " `mappend` k)
(fmap (Field . return)) $ parseJSON' Nothing
FromJSON 型クラスのインスタンスにすると JSON や
YAML をデコードできる
C 型の制約を満たす Record 型
型クラス
実は前の定義が parseJSON' になってる
YAMLのフィールドが無いときに Nothing にしたい
ので
class FromJSON a => FromJSON' a where
parseJSON' :: Maybe Value -> Maybe (Parser a)
instance FromJSON a => FromJSON' a where
parseJSON' = fmap parseJSON
instance {-# OVERLAPS #-} FromJSON a => FromJSON' (Maybe a) where
parseJSON' = Just . maybe (pure Nothing) parseJSON
関数
main :: IO ()
main = do
[gfp, ffp] <- getArgs
glangs <- Y.decodeEither . fromString <$> readFile gfp
flangs <- eitherDecode . fromString <$> readFile ffp
-- glangs :: Either String GitHubLanguages な点に注意
either print print' $ diff <$> glangs <*> flangs
print' :: HM.HashMap Text (GitHubLanguage, FastHubLanguage) -> IO ()
print' = mapM_ print . HM.toList
diff :: GitHubLanguages -> FastHubLanguages
-> HM.HashMap Text (GitHubLanguage, FastHubLanguage)
diff = undefined
関数
diff :: GitHubLanguages -> FastHubLanguages
-> HM.HashMap Text (GitHubLanguage, FastHubLanguage)
diff glangs flangs =
HM.filter ((a, b) -> not $ eqColor a b) $
HM.mapMaybeWithKey (k v -> (,) v <$> HM.lookup k flangs) glangs
-- mapMaybeWithKey :: (k -> a -> Maybe b) -> Map k a -> Map k b
eqColor ::
( Associate "color" (Maybe Text) xs
, Associate "color" (Maybe Text) xs')
=> Record xs -> Record xs' -> Bool
eqColor lang1 lang2 = lang1 ^. #color == lang2 ^. #color
eqColor a b に a と b の型が同じという制約はない
が, eqColor 関数は可換である
実行
いちゃもん(PR)だした
そっこうマージされた(笑)
まとめ
Haskell はラフに使っても楽しいよ
おしまい

More Related Content

More from Nobutada Matsubara

Haskell で作る競技型イベントの裏側
Haskell で作る競技型イベントの裏側Haskell で作る競技型イベントの裏側
Haskell で作る競技型イベントの裏側
Nobutada Matsubara
 
Marp Next Theme: Colors
Marp Next Theme: ColorsMarp Next Theme: Colors
Marp Next Theme: Colors
Nobutada Matsubara
 
Marp Next Tips !
Marp Next Tips !Marp Next Tips !
Marp Next Tips !
Nobutada Matsubara
 
貧者のための「cron」
貧者のための「cron」貧者のための「cron」
貧者のための「cron」
Nobutada Matsubara
 
Build Dockferile with Haskell
Build Dockferile with HaskellBuild Dockferile with Haskell
Build Dockferile with Haskell
Nobutada Matsubara
 
Elixir Programming with Type checking
Elixir Programming with Type checkingElixir Programming with Type checking
Elixir Programming with Type checking
Nobutada Matsubara
 
MixML 作ってみる
MixML 作ってみるMixML 作ってみる
MixML 作ってみる
Nobutada Matsubara
 
Elm でなんかつくる
Elm でなんかつくるElm でなんかつくる
Elm でなんかつくる
Nobutada Matsubara
 
ADVENTAR の Bot を作る with Haskell
ADVENTAR の Bot を作る with HaskellADVENTAR の Bot を作る with Haskell
ADVENTAR の Bot を作る with Haskell
Nobutada Matsubara
 
Haskell Backpack 事始め
Haskell Backpack 事始めHaskell Backpack 事始め
Haskell Backpack 事始め
Nobutada Matsubara
 
日記って続かないよね...
日記って続かないよね...日記って続かないよね...
日記って続かないよね...
Nobutada Matsubara
 
「7つの言語、7つの世界」を読む
「7つの言語、7つの世界」を読む「7つの言語、7つの世界」を読む
「7つの言語、7つの世界」を読む
Nobutada Matsubara
 
Lisper はじめました (再)
Lisper はじめました (再)Lisper はじめました (再)
Lisper はじめました (再)
Nobutada Matsubara
 
Haskell で LINE Bot を作ってみた
Haskell で LINE Bot を作ってみたHaskell で LINE Bot を作ってみた
Haskell で LINE Bot を作ってみた
Nobutada Matsubara
 
Marp colors
Marp colorsMarp colors
Marp colors
Nobutada Matsubara
 
Marp Tips
Marp TipsMarp Tips
Whitespcae 入門
Whitespcae 入門Whitespcae 入門
Whitespcae 入門
Nobutada Matsubara
 
入門 超絶技巧プログラミング !
入門 超絶技巧プログラミング !入門 超絶技巧プログラミング !
入門 超絶技巧プログラミング !
Nobutada Matsubara
 
SKIコンビネーターによる処理系の作成
SKIコンビネーターによる処理系の作成SKIコンビネーターによる処理系の作成
SKIコンビネーターによる処理系の作成
Nobutada Matsubara
 
Ruby4Ctf
Ruby4CtfRuby4Ctf

More from Nobutada Matsubara (20)

Haskell で作る競技型イベントの裏側
Haskell で作る競技型イベントの裏側Haskell で作る競技型イベントの裏側
Haskell で作る競技型イベントの裏側
 
Marp Next Theme: Colors
Marp Next Theme: ColorsMarp Next Theme: Colors
Marp Next Theme: Colors
 
Marp Next Tips !
Marp Next Tips !Marp Next Tips !
Marp Next Tips !
 
貧者のための「cron」
貧者のための「cron」貧者のための「cron」
貧者のための「cron」
 
Build Dockferile with Haskell
Build Dockferile with HaskellBuild Dockferile with Haskell
Build Dockferile with Haskell
 
Elixir Programming with Type checking
Elixir Programming with Type checkingElixir Programming with Type checking
Elixir Programming with Type checking
 
MixML 作ってみる
MixML 作ってみるMixML 作ってみる
MixML 作ってみる
 
Elm でなんかつくる
Elm でなんかつくるElm でなんかつくる
Elm でなんかつくる
 
ADVENTAR の Bot を作る with Haskell
ADVENTAR の Bot を作る with HaskellADVENTAR の Bot を作る with Haskell
ADVENTAR の Bot を作る with Haskell
 
Haskell Backpack 事始め
Haskell Backpack 事始めHaskell Backpack 事始め
Haskell Backpack 事始め
 
日記って続かないよね...
日記って続かないよね...日記って続かないよね...
日記って続かないよね...
 
「7つの言語、7つの世界」を読む
「7つの言語、7つの世界」を読む「7つの言語、7つの世界」を読む
「7つの言語、7つの世界」を読む
 
Lisper はじめました (再)
Lisper はじめました (再)Lisper はじめました (再)
Lisper はじめました (再)
 
Haskell で LINE Bot を作ってみた
Haskell で LINE Bot を作ってみたHaskell で LINE Bot を作ってみた
Haskell で LINE Bot を作ってみた
 
Marp colors
Marp colorsMarp colors
Marp colors
 
Marp Tips
Marp TipsMarp Tips
Marp Tips
 
Whitespcae 入門
Whitespcae 入門Whitespcae 入門
Whitespcae 入門
 
入門 超絶技巧プログラミング !
入門 超絶技巧プログラミング !入門 超絶技巧プログラミング !
入門 超絶技巧プログラミング !
 
SKIコンビネーターによる処理系の作成
SKIコンビネーターによる処理系の作成SKIコンビネーターによる処理系の作成
SKIコンビネーターによる処理系の作成
 
Ruby4Ctf
Ruby4CtfRuby4Ctf
Ruby4Ctf
 

GitHub での Haskell の色が変わったんで