Just $ A sandbox

プログラミングと計算機科学とかわいさ

Haskellで躓いた(躓いてる)ポイントまとめ への自分なりの回答

qiita.com

こんなふうに各位を焚き付けてしまったのでせっかく色々まとめていただいた記事に対して自分なりに回答をしてみようと思ったので記事をかくことにした

ただしあくまでこれは 私個人的な意見でありコミュニティの総意でも唯一の正解でもない ことを重々ご承知くださいとだけ

色んな意見があっていいと思います(マサカリ回避の構え)

  • 高階関数が分からない: 慣れかなぁ 逆に慣れたら高階関数とそうでない関数を分ける意味がわからなくなる気がする(世の中には高階関数が扱えない言語があるって聞いた)
  • 本は1冊終わったけど次やることが分からん: コマンドラインで動く簡単なツールやらゲームやらスクリプトやらを書いてみるのがいいんではなかろうか
  • 何から始めればいいかが分からない: 本を読む→簡単なものを作ってみる→使えそうなライブラリを勉強する→プロダクトに反映する→またライブラリの勉強するをループする感じ
  • 部分関数こわい: せやろか
  • モナドって何: コンピュテーションを解釈するための型クラス
  • 変数に再代入出来ないとか正気か?: (模範解答)そもそも変数あるいは可変な状態から脱却したプログラミングスタイルに慣れてほしい (だめな解答) D a t a . I O R e f
  • fold系が分からない: わかる 未だに自分もfoldより再帰書いたりしちゃうので少しずつ慣れていけばいいと思う
  • unfoldがもっと分からない: DPしたいときくらいしか使わなくない?
  • 型にIOが付いてしまうと泣きたくなる: モナドを理解しましょう
  • Stateが分からない: モナドを(ry
  • doが怖い: モナ(ry do-notation慣れたら(>>=)とかよりずっと楽に感じられるはず
  • 関数型プログラミングって何: 知らない知らない私は何も知らない
  • ポイントフリースタイルこわい: 可読性の上でも後で書き換える手間の上でも最低限にしたほうがいいと思う

  • パーサーが理解し辛い: Persecモナドは内部実装よりそれが表すcomputationを理解しちゃう方が楽だと思う
  • GHCが分からない: 内部実装よくわからないわかるぅ〜
  • stackがもっと分からない: stackは日々進化してるし進化しすぎて情報が古くなりがちなので細かいところはなるべく公式ドキュメントを参照するようにしたほうがいいかも https://docs.haskellstack.org/en/stable/README/
  • cabalが更にもっと分からない: cabalファイルもhpackで生成する時代だしcabalとか投げ捨てていいのでは?
  • モナドが分かったか分かってないかが分からない: State, IO, Persecあたりで普通にプログラムかけたら多分分かってる方なんじゃなかろうか
  • モナド変換子が分からない: 1. モナドをより大きなモナドに変えられる 2. ベースのモナドのアクションをliftできる みたいなノリでこう(説明になってねぇ)
  • 「理解は出来てないけど使えるようにはなった」をいつまで放置して良いのか: 全てを理解出来てる人いなさそう
  • 関数をどれぐらい分割すれば良いか分からない: 限りなく細かく
  • typeとnewtypeが分からない: typeはただのエイリアス newtypeは別の型
  • UI関連の情報が少ない: UIツライ そもそもHaskellでこういうのに果敢にチャレンジする人あんまりいない感じある
  • 特にTUI: brick好きだけど使ってる人ほぼ見たことない
  • 文字列型が多い: 基本StringでムカついてきたらText
  • 結局圏論は必須なのかどうなのか: いらない派(使ってるお前が言うんじゃねーよ!わかる)
  • インデントスタイルが「これかこれかこれが多いよ」的なのが無い(あったとして、情報が纏まってない): インデント、みんなノリなのでは…お使いのエディタにそれっぽいプラグイン入れてそれに合わせるとか
  • 関数の名前付けがネタ切れする: 名前が思いつかない→分割が足りてない 名前が被る→わかる(わかるじゃなくて)
  • .と$の違いは分かるけど, いつのタイミングでどっちかの判断がし辛い: なるべく . 使いましょう (でも私は a $ b $ ca . b $ c にするのあんまり好きじゃないのでやらないけど)
  • 関数型プログラミングは分かるけど関数型プログラミングが出来てるかが分からん: 自然に小さな関数を組み合わせてプログラムを組むってことができていればいいんじゃないかな
  • 言語拡張怖い: わかり〜〜〜
  • 逆引き的なの欲しい: こういうのはやはりコミュニティのちからを使ってみんなでちまちま作っていくしかなさそう
  • キモいコードが出てきた時にお手上げ: キモいコードは書く奴が悪い
  • 見たことない演算子がいっぱい: stackでhoogleできるらしいしそれ使うか、stackageの検索もhoogleなのでそれでも出来ますよ
  • その時は理解できても, 次回必要になった時結局使えない: 一般に理解することと使いこなせることはまた別なので
  • 結局letは使わないべきなのか: 使うべき 早く使ってあげてください
  • というか禁じ手一覧が欲しい: そういうのも逆引きと同じくみんなで作っていって欲しい
  • 自分が書いているコードが関数型プログラミングをちゃんと出来ているかが分からない: 上に同じ
  • 自分のコードが汚くて嫌い: 綺麗になるまでがんばりましょう
  • 他人のコードが難しすぎて理解できず, 結局写経しても理解できない: 他人のHaskellコード読む気にならないわかる
  • どのライブラリが良いのか分からん: 色々使ってみて判断しましょう
  • 写経ですら動かないサンプルコードが多い: これは文句言うべき案件では
  • cabalで書かれても入れ方分からん: 今時大体stack installで入りそう
  • Lazy IO怖い: わかるぅ〜〜〜

補足

逆引き的なの

http://dev.stephendiehl.com/hask/

https://github.com/haskell-jp/recipe-collection

この辺かしら

検索したい

https://www.stackage.org/

stackageに入っている奴は全部検索できるはず

関数の命名について

関数の名前が被りそうな時に以下の命名をよくやる気がする

  1. 類義語を使う(call→invokeとか、get→obtainとか): ボキャブラリー誰かくれ〜〜〜
  2. 2単語以上くっつけてみる(callWhenHogeとか makeSomethingとか): かっこわるいけど致し方ない
  3. 似た発音の別の文字にする(class→klassとか、func→fankとか): おしゃれ感あるけど後から見てナニコレってなりそうなので私は避けてます
  4. そもそも関数にしない: 似たような名前の関数を複数定義する前に、それは実は1つのgeneralな関数に抽象化出来ませんか?とか 関数じゃなくて専用のデータ型を作ってデータコンストラクタとして与えられませんか?とか ちょっと上級者向きかも

ポイントフリースタイルについて

関数型プログラミングしてて、関数を組み合わせてプログラムを書くスタイルでは自然と f . g . h みたいな感じになるはずなので関数型プログラミングにおいて自然と発生する書き方がポイントフリースタイルというものなのだと思えばよいのではなかろうか。

少なくともそれは無理に頑張ってそうしたりするようなものではなくてあくまでたまたまそういうのがよく出てくるよねぐらいの気持ちでいいと思います