19 ポイント 投稿者 GN⁺ 2024-09-13 | 3件のコメント | WhatsAppで共有
  • 「非実用的」「学術的」「ニッチ」

    • 人々が、私のいちばん好きなプログラミング言語がHaskellだと知ったときに示す反応
    • 趣味のプロジェクトだけでなく、実際のWebサーバーを構築するのにも使っている
    • ConvergeでHaskellで作業するチームを率いている
  • Haskellに対する誤解

    • 汎用プログラミング言語で解ける問題は、他の言語でも解ける
    • Python、Rust、Typescriptなどに導入されている多くの機能は、Haskellに着想を得たか、Haskellではより堅牢に実装されている
    • 「退屈な技術を選べ」という理念の派生形のように見える
    • プログラミングは数学ではなく、数学的要素を排除すべきだという誤った考えがある
  • この記事の目的

    • Haskellが大半のプログラマーにとって最良の選択である理由を論理的に説明しようとしている
    • 堅牢なソフトウェアを生産的に書きたい人にとって、特に有用である
    • ソフトウェアを書くうえでの楽しい側面も強調している
  • アンラーニングとリラーニング

    • ほとんどのプログラマーは命令型パラダイムに慣れている
    • Haskellは純粋関数型言語であり、学習曲線は急である
    • Haskell言語自体は、単純な部分集合に限定すれば学びやすい
    • 関数型プログラミングは、プログラムを構成する方法についての完全な転換を要求する
    • この過程は、プログラマーとして成長する助けになる
    • Alan Perlisの言葉の引用:

      プログラミングについての考え方に影響を与えない言語は、知る価値がない。

文法の簡単な説明

  • :: は型シグネチャを表す(例: myThing :: String

  • 関数呼び出しは括弧を使わず、関数名の後ろに引数を空白区切りで並べる(例: doSomething withThis withThat

  • 型シグネチャの小文字は型変数で、任意の型を表す(例: head :: [a] -> a

  • 2種類の矢印 ->=> がある:

    • -> は関数の型を説明する(例: add1 :: Int -> Int
    • => は型変数に対する制約を説明し、常に先に来る(例: add1 :: Num a => a -> a
  • コメントは -- で始まる

  • return は通常の関数であり、想像するような意味ではない

  • do は命令型のように見せるための糖衣構文である

  • ローカル変数に値を割り当てる方法はいくつかある:

    let x = <something> in  
    <expression>  
    

    または x <- <something>

  • ミスを減らす

    • 多くの言語では、コードを「正しく」するために多数のテストケースを書く
    • Haskellは型システムと純粋関数型プログラミングによって、この負担を大幅に減らす
    • Haskellの強力な型システムは、プログラムに対する具体的な保証を提供し、それを厳格に適用する
    • 型システムの特徴:
      • nullableな型がない
      • 失敗しうる計算を表現できる
      • パターンマッチと網羅性チェック
      • Primitive Obsessionを自然に回避できる
  • null値がないことの利点

    • null 値が存在しないため、値が期待する型に属しているかを常に把握できる
    • 実行時エラーを防ぎ、エラーの表面積を減らす
  • 失敗しうる計算の表現

    • MaybeEither 型を使って、失敗しうる計算を明示的に表現する
    • Maybe は、結果があるかもしれないし、ないかもしれない計算を表す
      safeHead :: [a] -> Maybe a  
      
    • Either は2種類の値を持ちうる(Left a または Right b
      validateAddress :: String -> Either AddressParseError ValidAddress  
      
  • パターンマッチと網羅性チェック

    • すべての入力ドメインを扱わなければならず、そうでなければコンパイラがエラーを出す
    • これは実行時エラーを防ぎ、プログラムの信頼性を高める
  • Primitive Obsessionの回避

    • newtype を使って、意味論的により明確な型を簡単に作れる
    newtype VenueName = VenueName String  
    newtype EventName = EventName String  
    
  • 純粋関数型プログラミングの利点

    • データは不変であり、状態変化を心配する必要がない
    • 副作用は明示的に扱われ、関数は副作用なしに入力のみに依存する
    • これにより、プログラムの予測可能性と安定性が高まる
  • 副作用の明示的な処理

    • IO モナドを使って、副作用をコードから分離し制御する
    • 関数の型シグネチャを通じて、副作用を起こす関数であることが分かる
    sendGreetings :: User -> IO Response  
    
  • モナドと効果の制御

    • 型クラスとモナドを使って、関数が実行できる効果を正確にエンコードする
    • これにより、意図しない副作用を防ぎ、コードの安定性を高める
  • 生産性を高める要素

    • 強力な型システムと純粋関数型という特性により、コード再利用と概念の一般化が容易になる
    • FunctorMonoid のような概念を通じて、さまざまなデータ構造に同じパターンを適用できる
    fmap (+2) [1, 2, 3] -- [3, 4, 5]  
    fmap (+2) (Just 2) -- Just 4  
    
  • 恐れずにできるリファクタリング

    • コンパイラの厳格さにより、コード変更時に新しいバグが発生するリスクが少ない
    • 型システムがプログラムのドメインを正確に表現できるようにしてくれるため、安心してコードを修正できる
  • プログラム理解の向上

    • 宣言的プログラミングによって、問題ドメインを正確に表現できる
    • プログラムの意味を理解しやすくなり、信頼性も高められる
    • 不要な複雑さを取り除くことで、プログラムを合理的に推論できるようになる
  • 代数的データ型と型クラス

    • Haskell内でドメイン特化言語を構築できる
    • これはプログラムの理解と保守に役立つ
  • サンプルプログラム

    • 簡単な会計ツールを書いて、Haskellの概念を実践的に適用する

エピローグ

  • Haskellを使うことは楽しく、生産的である
  • 強力で表現力の高い型システムと純粋関数型プログラミングの組み合わせが、Haskellを特別なものにしている
  • 他の言語もこうした機能を導入しているが、Haskellではそれらの特徴が根本に据えられている
  • Haskellを学ぶことは、プログラミングに対する考え方を変えてくれるだろう

GN⁺の意見

  • Haskellの学習価値

    • プログラマーとして思考の幅を広げる助けになる
    • 関数型プログラミングのパラダイムを理解すれば、他の言語でもより良いコードを書ける
  • 関数型プログラミングの台頭

    • 並列処理と並行性に強みがあり、現代のコンピューティング環境に適している
    • 副作用を制御することで、予測可能なコードを書ける
  • 他の言語との比較

    • RustやScalaのように関数型プログラミングを支援する言語もあるが、Haskellの純粋性と型システムは際立っている
    • 新しい言語を学ぶ際にも、Haskellの概念は役立ちうる
  • 実務への適用可能性

    • 初期の学習曲線は急だが、投資した時間に見合うだけの生産性向上が得られる
    • 複雑なシステムやエラーに敏感なドメインで有用である
  • コミュニティとエコシステム

    • Haskellコミュニティは活発で、多様なライブラリやツールが継続的に開発されている
    • オープンソースプロジェクトに参加して、実力を高めることができる

3件のコメント

 
cosine20 2024-09-19

私は実用性を加えたF#から入門しました

 
savvykang 2024-09-13

ADTとパターンマッチングはいいけど、モナドとかファンクターとかいう話はあまりしないでください

 
GN⁺ 2024-09-13
Hacker Newsの意見
  • Haskellは部分関数ではなく全域関数を書くよう強制する

    • Haskellは無限再帰を防がない
    • 依存型へ移行するFPエコシステムでは、型チェッカーが無限に実行されないようにすることが重要
    • Haskellの多くのその場しのぎの拡張機能が問題を引き起こしている
    • Haskellの哲学が好きなら、Haskellだけに限定すべきではない
    • Haskellの標準化は失敗した
    • GHC独自の価値提案はGHCランタイムシステムかもしれない
  • Haskellを10年間使ってきたが、ツールは大きく改善された

    • ghcup、cabal sandboxing、HLSは安定している
    • ライブラリエコシステムで大きな不足を感じることはあまりなかった
    • Haskellのコンパイル時間はいまだに不便
    • 依存関係のコンパイル時間が長い
  • Haskellの型システムは関数が全域的であることを証明しない

    • 一般的なプログラミングでは、全域性の証明は有用ではない
    • ほとんどの人は、プログラムが実際に動くかどうかをテストで確認する
  • Haskellという言語は良いが、エコシステムはまだ道半ば

    • コンパイラが遅い
    • エラー報告能力が不足している
    • 最初のエラーで残りのコンパイルが止まる
    • ツールは他の関数型言語と比べてもまだ不足している
    • ライブラリエコシステムが弱い
    • Haskellのアイデアは他の多くの言語に影響を与えた
  • Haskellや他の関数型言語を仕事で使いたい

    • Goのような言語は簡単に学べた
    • 関数型言語でコードベースを構築する方法を学びたい
  • Haskellはプログラミングの考え方とコードアーキテクチャに大きな影響を与えた

    • Haskellの型システムは非常に強力で理解しやすい
    • Haskellコードを細かく最適化するのは楽しかった
    • ツールは依然として不足している
  • Haskellは言語レベルで遅延評価を実験している

    • 遅延評価は標準ライブラリのレベルで得られる
  • Haskellの極端な純粋性と不変性が問題

    • 多くのプログラマーは手続き的/可変なループのほうが表現しやすい
    • Rustは有能な型システムと多くの関数型イディオムを使うが、ループと可変性も使える
  • Haskellはビジネスロジックソフトウェア(BLOBS)に非常に適している

    • シンプルな型とパターンマッチングで、ほとんどのビジネスロジックをモデル化できる
    • 単純な部分を保てば、非技術系の貢献者にも簡単に教えられる
    • Haskellは楽しい