New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Procに関数合成を実装する #13

Open
yuroyoro opened this Issue Aug 31, 2017 · 6 comments

Comments

Projects
None yet
3 participants
@yuroyoro

yuroyoro commented Aug 31, 2017

概要

Proc#compose でProc同士を合成できるようにする。
f.compose g で、 Proc{|x| f.call(g.call(x)) } となるProcを生成する

f = Proc.new{|x| x + 1 }
g = Proc.new{|x| x * x }

f.compose(g).call(2) #=> 5

雑な実装イメージはこんな感じ

class Proc
  def compose(f)
    Proc{|x| self.call(f.to_proc.call(x)) }
  end
end

逆方向の関数合成のサポート

さらに、 Proc#reverse_compose で 逆の関数合成もできるようにする。 f.reverse_compose(g).call(x) == g.compose(f).call(x) となる。

Proc#>>Proc#<< にaliasする

alias_method :<<, :composealias_method :>>, :reverse_compose にaliasしておくことで利便性が向上する

Symbol への拡張

Symbol にも compose および reverse_compose を実装する。 実装はself.to_proc.compose するだけ

モチベーション

以下のようなコードは、関数合成があればすっきりと記述できる

arr = [:foo, :bar, :baz]

# arrをto_sしてupcaseする

# blockを書く場合
arr.map{|v| v.to_s.upcase } 
# mapを2回書く場合
arr.map(&:to_s).map(&:upcase) 

# composeを使うとこのように書ける
arr.map(&:to_s.to_proc.compose(&:upcase))

# さらに、 >> を使うと呼び出しの流れを可視化できる
arr.map(&:to_s.to_proc >> :upcase.to_proc)

# Symbolに >> が実装されていればさらにすっきりする
arr.map(&:to_s >> :upcase)
@riseshia

This comment has been minimized.

Show comment
Hide comment
@riseshia

riseshia Aug 31, 2017

おーどこかでみたcompositionだ!!!

riseshia commented Aug 31, 2017

おーどこかでみたcompositionだ!!!

@shunsakai

This comment has been minimized.

Show comment
Hide comment
@shunsakai

shunsakai commented Aug 31, 2017

この辺読んだことあります!
http://yuroyoro.hatenablog.com/entry/2012/08/10/232443

@yuroyoro

This comment has been minimized.

Show comment
Hide comment
@yuroyoro

yuroyoro Aug 31, 2017

はい、この記事と、以前作ったgemをCレベルで実装してみます

yuroyoro commented Aug 31, 2017

はい、この記事と、以前作ったgemをCレベルで実装してみます

@yuroyoro

This comment has been minimized.

Show comment
Hide comment
@yuroyoro

yuroyoro commented Aug 31, 2017

実装 : yuroyoro/ruby#7

@yuroyoro

This comment has been minimized.

Show comment
Hide comment
@yuroyoro

yuroyoro Aug 31, 2017

5年前にどの記法を採用するかで揉めてる…

https://bugs.ruby-lang.org/issues/6284

yuroyoro commented Aug 31, 2017

5年前にどの記法を採用するかで揉めてる…

https://bugs.ruby-lang.org/issues/6284

@yuroyoro

This comment has been minimized.

Show comment
Hide comment
@yuroyoro

yuroyoro commented Aug 31, 2017

上記のIssueにcommented.

https://bugs.ruby-lang.org/issues/6284#note-50

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment