こんにちは!
Waffle College 2期生の こはる です!
どんな内容ならみんなと被らないだろう。。。と悩んだ結果、最近よく触っているHaskellのWebアプリケーションフレームワークYesodについて書くことにしました🙌
そもそもHaskellとは?
公式ドキュメントでもHaskellの入門として紹介されている Learn You a Haskell for Great Good! によると、Haskellは以下のような特徴を持つと書かれています。
- Haskell is a purely functional programming language.
- Haskell is lazy.
- Haskell is statically typed.
- Haskell uses a very good type system that has type inference.
- Haskell is elegant and concise.
つまり、純粋関数型言語で、遅延評価・静的型付けを採用していて、型推論システムを持つ簡潔で優雅な言語です!!(?????)
本記事ではHaskellについての詳しい解説は省きますが、もし興味のある人はぜひ以下のサイトとか見てみてください👀❤️🔥
Yesod
Yesodはプログラミング言語Haskellに基づくWebアプリケーションフレームワークです。
Webアプリ開発といえば、JavaScriptやRuby、Java、Python、Goなどですよね。
、、、でもHaskellでWebアプリ作れたらカッコよくないですか?🥺 というわけでYesodを使って簡単なWebアプリを作る方法をざっっっっくりとご紹介します!
環境構築
公式ドキュメントに沿って環境構築していきます。
1. Stackをインストール
Stackとは、依存関係を管理してくれるHaskellのビルドツールです。
以下のスクリプトを実行してインストールします。
$ curl -sSL https://get.haskellstack.org/ | sh
2. 新規プロジェクトの作成
sqliteというYesodのテンプレートを使用して、my-projectという新しいHaskellプロジェクトを作成します。Yesodテンプレートrepo によると他にはmaster, postgresなどのテンプレートがあるみたいですね👀
$ stack new my-project yesodweb/sqlite && cd my-project
3. コマンドラインツールをインストール
Yesodフレームワークを使うためのコマンドラインツールyesod-binをインストールします。
--install-ghc
というオプションをつけることでコンパイラGHCを自動でインストールしてくれます。
$ stack install yesod-bin --install-ghc
4. ビルドして確認
エラーが出なければOK!
$ stack build
5. サーバを立ち上げる
$ stack exec -- yesod devel
6. サイトを確認
http://localhost:3000/ にアクセスし、以下のページが表示されたら成功です👏❤️🔥ワーイ
実際に作ってみる
Hello World!
以下のコードを先ほどのmy-project/app/ に helloworld.hs
として保存します。
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
import Yesod
data HelloWorld = HelloWorld
mkYesod "HelloWorld" [parseRoutes|
/ HomeR GET
|]
instance Yesod HelloWorld
getHomeR :: Handler Html
getHomeR = defaultLayout [whamlet|Hello World!|]
main :: IO ()
main = warp 3000 HelloWorld
以下のコマンドで実行すると
$ stack runghc app/helloworls.hs
簡単にコードの説明をします。流れとしてはこんな感じです。
helloworld.hs
が実行されるとwarp関数によりポート番号3000にサーバが立ち上がる。
http://localhost:3000/ からこのアプリケーションにアクセスすると(=ホーム/にアクセスすると)getHomeR関数が実行される。
getHomeR関数は以下のHTMLと同様の内容を表示させる。
<!DOCTYPE html>
<html><head><title></title></head><body>Hello World!</body></html>
とりあえずYesodはHaskellファイル内で[whamlet|...|]
を使えばHTMLを扱えるようにすることができるやつなんだ〜!という認識でOKです(◜‧̮◝ )
CSS
Webアプリを作るならHTMLの他にCSSも必要不可欠ですよね。実はLuciusというCSSのテンプレート言語を用いることでHaskellでCSSも書けちゃうんです!
Hello World!をもっと可愛くしてみましょう。
先ほどのコードに数行加えます。
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
import Yesod
import Text.Lucius (luciusFile)
data HelloWorld = HelloWorld
mkYesod "HelloWorld" [parseRoutes|
/ HomeR GET
|]
instance Yesod HelloWorld
getHomeR :: Handler Html
getHomeR = do
css <- withUrlRenderer $(luciusFile "app/template.lucius")
defaultLayout $ do
toWidget css
[whamlet|
<h1>Hello World!
|]
main :: IO ()
main = warp 3000 HelloWorld
そしてappの下にtemplate.lucius
というファイルを作ります。ここでCSSの処理を書きます。
@import url('https://fonts.googleapis.com/css2?family=Sacramento&display=swap');
h1 {
color: #FFFFFF;
font-family: 'Sacramento', cursive;
font-size: 100px;
text-align: center;
}
body {
background-color: #FF99CC;
}
もう一度 stack runghc app/helloworls.hs
コマンドで実行してみましょう。
かわいすぎる〜〜〜!!!!!🩷🩷
Hello World!がCSSのおかげでとってもかわいくなりました。template.lucius
内にCSS処理を書き、それを読み込むことでHaskell内でCSSを使うことができました。
JavaScript
てことはなんかJavaScriptもHaskellで扱えそうな気がしてきました。その通りです。JuliusというJavaScriptのテンプレート言語を使います。
先ほどのhelloworld.hs
、template.lucius
に数行ずつコードを加えます。
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
import Yesod
import Text.Lucius (luciusFile)
import Text.Julius (juliusFile)
data HelloWorld = HelloWorld
mkYesod "HelloWorld" [parseRoutes|
/ HomeR GET
|]
instance Yesod HelloWorld
getHomeR :: Handler Html
getHomeR = do
css <- withUrlRenderer $(luciusFile "app/template.lucius")
js <- withUrlRenderer $(juliusFile "app/template.julius")
defaultLayout $ do
toWidget css
toWidget js
[whamlet|
<h1 id="floating-text">Hello World!
|]
main :: IO ()
main = warp 3000 HelloWorld
@import url('https://fonts.googleapis.com/css2?family=Sacramento&display=swap');
h1 {
color: #FFFFFF;
font-family: 'Sacramento', cursive;
font-size: 100px;
text-align: center;
}
body {
background-color: #FF99CC;
}
@keyframes float {
0% { transform: translateY(0); }
50% { transform: translateY(-40px); }
100% { transform: translateY(0); }
}
#floating-text {
animation: float 3s infinite;
margin-top: 100px;
}
そしてappの下にtemplate.julius
というファイルを作ります。ここにJSの処理を書きます。
document.addEventListener("DOMContentLoaded", function() {
const text = document.getElementById("floating-text");
text.addEventListener("mouseover", function() {
text.style.color = "red";
text.style.transition = "color 0.5s";
});
text.addEventListener("mouseout", function() {
text.style.color = "#FFFFFF";
});
});
もう一度 stack runghc app/helloworls.hs
コマンドで実行してみましょう。
❤️🩷かわいすぎる〜〜〜!!!!!🩷❤️
原理的には先ほどのCSSと同じです。JSを使うことによってHello World!をぷかぷか浮かせてマウスオーバー処理を加えることができました。
他にもデータベースと接続したり、フォーム使ったり、デプロイしたり、、、とYesodを使えば色々実装できるので興味を持った方は見てみてください!
どうしてHaskell?
どうしてこんな面倒くさいことをしてまでHaskellでWebアプリを作る必要があるのでしょうか。わたしはただ、既存のHaskellのシステムを触るためのGUIシステムを開発するために使い始めただけですが、個人的には以下の理由があるかなと思います。
- 高速なアプリケーションを構築できる
- Haskellは静的型付きでコンパイルされるため、Yesodも処理が高速
- 堅牢なシステムを構築できる
- URLを文字列として手動ではなくHaskellの型システムを利用して組み立てることによって、安全にURLを生成できる
- ハンドラー関数とURLを自動で対応づけてくれるのでルーティング処理が自動で行われる
終わり
普段はもう少しスケールの小さい記事を書くことが多いので、技術をざっくばらんに紹介するこういった記事を書くのってとても難しいなと思いました。(いつも書いてくれている世界中の皆様にびっぐ感謝。。。。。)
ほへーHaskellっていう言語でもWebアプリ開発できるんだーふむふむとなってくれれば本望です。まだまだ勉強途中なので、何かあればコメントお願いしますっ🥳
ありがとうございました!
明日以降の記事も楽しみだーーーーー!!!!!