0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

関数型プログラミングをかじってみた。

Posted at

🏆 1. 導入 - fp-goで遊ぼうと考えたきっかけ

Goで関数型プログラミングに興味を持った背景

  • 数学が好きな自分にとって、プログラミングに数学を持ち込むという思想に興味が湧いた。
  • 実際に遭遇した課題・悩み
    • エラーハンドリングが煩雑
    • テストがしにくい

fp-go を選んだ理由

  • 手っ取り早く関数型プログラミングを体験することができると考えたから

🔎 2. 実践 - 実際に何をやったか

基本概念

  • fp-goを活用して簡単なアプリを作成してみた
    • モナド三兄弟を積極的に活用した。

コード例

  • 通常のGoコードと fp-go コードの比較

Before: 通常のGoコード

func (s User) Login(authCode string) (dto.UserInformation, error) {
	// 認証APIからユーザー情報を取得
	user, err := s.authorizeAPI.GetUserInfo(authCode)
	if err != nil {
		return dto.UserInformation{}, err
	}

	// ユーザーのメールアドレスを取得
	email := user.GetEmailObject()

	// 重複チェック
	isDuplicate, err := domainservice.CheckDuplicate(s.userRepository, email)
	if err != nil {
		return dto.UserInformation{}, err
	}

	var userInfo user.User
	if isDuplicate {
		// 重複している場合、ユーザー情報を取得
		userInfo, err = s.userRepository.GetUserInformation(email)
		if err != nil {
			return dto.UserInformation{}, err
		}
	} else {
		// 重複していない場合、ユーザー情報を保存
		userInfo, err = s.userRepository.SetUserInformation(user)
		if err != nil {
			return dto.UserInformation{}, err
		}
	}

	// DTOに変換して返却
	return dto.NewUserInformation(userInfo), nil
}

After: fp-goでのGoコード

func (s User) Login(authCode string) E.Either[error, dto.UserInformation] {
	userE := s.authorizeAPI.GetUserInfo(authCode)
	idE := E.Map[error](
		func(user user.User) email.Email {
			return user.GetEmailObject()
		})(userE)

	return FP.Pipe4(
		E.Right[error](domainservice.CheckDuplicate(s.userRepository)),
		E.Ap[E.Either[error, bool]](idE),
		E.Flatten,
		E.Chain(
			func(duplicate bool) E.Either[error, user.User] {
				if duplicate {
					return E.Chain(s.userRepository.GetUserInformation)(idE)
				}
				return E.Chain(s.userRepository.SetUserInformation)(userE)
			}),
		E.Map[error](dto.NewUserInformaiton),
	)
}

✅ Either で成功/失敗を型で管理

🏆 3. 感想 - fp-go を使って感じたこと

🌟 メリット

コードの可読性が向上

  • Either を使うことで成功/失敗の分岐が一目でわかる
  • パターンマッチにより、if文やswitch文を減らせる
  • 場合によっては、記述量が少なくなり、すっきりした

✅ テスト容易性

  • 例外処理がなくなったため、テストが容易
  • 直感的なテストになった。(純粋関数のテストが多いため。)

⚠️ デメリット

記述量が増える

  • 型パラメータや fp-go のラップ処理でコードが冗長になりがち
  • Goのシンプルなスタイルに慣れていると、コードが「難しく」見える可能性

学習コストが高い

  • Option, Either, IO などの概念に慣れる必要がある
  • いきなりチームで導入するにはハードルが高い

Go標準ライブラリとの相性

  • Go の error 型との互換性が微妙

🎯 4. まとめと展望

🔥 fp-go を導入して得られたこと

  • Either でエラーハンドリングを統一 → 可読性と保守性が向上
  • ✅ 関数型のアプローチでコードの再利用性がアップ
  • ✅ モナドと少しだけ仲良くなることができた
  • 🟥 Goは関数型での実装に不向きであるこように感じた
    • 型推論が強い言語で勉強してみるべき
  • ✅ 関数型プログラミングは楽しい!!

🔮 5. 参考リンク

🤔 6. 最後に

  • 関数型プログラミングの雰囲気を掴むには実際にアプリを作ってみるのが一番
    • 書いてみる→gpt等にレビューしてもらう→新しい概念を知るというループで少しずつ仲良くなろう
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?