haskellに入門してみる

にあえん

January 17, 2024

いろんな言語が気になる時期。ナナオです。

今回はHaskellに入門してみようと思います。

(以前「すごいHaskell」は読んだことがあるのですが、読むだけでコード書いてなかったのでほぼ忘れてしまいました。。もったいない!!)

Haskellのセットアップ

まずはHaskellを使える環境を作っていきます。

Windows11の環境でやります。(WSLは使わないのでお気をつけて!)

GHCupを使ってStackやGHCなどをまとめてインストールしちゃいましょう!!

(僕は最初Stackだけインストールすればいいか~とやっていたら、VSCodeの拡張機能がGHCupを使う感じになっていたので詰みました)

Haskellの環境構築2023

windowsの場合はかなり長いコマンドですが、以下でインストール可能です。

Set-ExecutionPolicy Bypass -Scope Process -Force;[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; try { Invoke-Command -ScriptBlock ([ScriptBlock]::Create((Invoke-WebRequest https://www.haskell.org/ghcup/sh/bootstrap-haskell.ps1 -UseBasicParsing))) -ArgumentList $true } catch { Write-Error $_ }

チュートリアルをやってみる

とりあえずこのページのチュートリアルをやってみましょう。

10分で学ぶHaskell - HaskellWiki

ghciは以下のように起動します。

stack ghci

ghciでは:tと打つことで、変数や関数の型について知ることができます。

ghci> :t filter
filter :: (a -> Bool) -> [a] -> [a]

これはなんかいい機能ですね。

まずは関数定義からやっていきましょう。

適当なプロジェクトを作成します。

stack new haskell-playground

これをVSCodeで開きます。

拡張機能もインストールしておきましょう。

Haskell Extension Pack - Visual Studio Marketplace

では関数を定義してみましょう。

factorial 0 = 1
factorial n = n * factorial (n - 1)

main = do
    print $ factorial 2

こんな感じでfactorial関数を定義しました。

printにはfactorialの結果を入力として渡したいので、$を使用します。いつも()使っていたのでなんか不思議な感覚です。

続けてオブジェクト指向言語によくあるfor文をhaskellで書いてみましょう。

haskellではfoldrなどの畳み込み関数を使用して配列を処理するのが通常のようですね。

Haskell でループする #Haskell - Qiita

Haskellの畳込関数に関して

プログラミングHaskellのfoldr, foldlの説明が秀逸だった件 - あと味

例えばリスト内の値をすべて合計する処理を考えてみます。

main = do
    print $ foldr (+) 0 [1..10] -- sum [1..10]と同じ

また、fold~にはいくつか種類があります。

末尾にrがついているものは右から畳み込み、lがついているものは左から畳み込みます。

遅延評価をしないfoldl’とfoldr’もあります。遅延評価をしないことで、リスト内の要素が多い場合でもスタックオーバーフローにならず実行できます。

import qualified Data.List as L

main = do
    print $ foldl (+) 0 (replicate 100000000 1) -- これはstack overflowになる
    print $ L.foldl' (+) 0 (replicate 1000000 1) -- こっちはならない!

次にライブラリをどう使うかを学びます。

インポートの方法はいくつかの種類があり、以下にまとめられています。

Haskell import いろいろ #Haskell - Qiita

import qualified Data.Map as M

まとめ

実際に動くものを作ってみよう!とおもって途中までやってみましたが、文章にする以前にまったくうまく動かないため、今回はここまでにします。。

もう少し事前知識を身に着けてから再チャレンジしたいと思います。

参考

さくっとHaskellの開発環境を整える(Stack)